[USACO2.2]派對燈 Party Lamps
阿新 • • 發佈:2018-12-13
連結
大意
有 盞燈
給定如下的變化方式
- 所有燈取反
- 所有奇數燈取反
- 所有偶數燈取反
- 所有 燈取反
給定最終狀態的部分燈的亮滅情況
假設一開始所有燈都是亮著的,求出在
步內可能達到與給定狀態部分對應相等的所有狀態
資料範圍:
思路
首先(
),一個燈按兩次等於沒按,按三次還不如按一次=所有方式至多選1次
接著(
),23方式的組合是等於1的,所有隻有可能123分於4綜合使用=多出三種變換方式,14,24,34
然後(
),第一種操作在所有範圍內都會被影響,23操作兩個兩個一組被影響,4操作三個三個一組被影響,
每六個數所受的影響相同=答案六個一組迴圈
最後( ),注意我也可以不做處理!
const int a[8][7]=//八種狀況
{0,0,0,0,0,0,0,//1
1, 0,0,1,1,1,0,//6=3+4 34組合
2, 0,1,0,1,0,1,//2
3, 0,1,1,0,1,1,//4
4, 1,0,0,1,0,0,//5=1+4 14組合
5, 1,0,1,0,1,0,//3
6, 1,1,0,0,0,1,//7=2+4 24組合
7, 1,1,1,1,1,1};//0 不做操作
程式碼
/*
ID:hzbismy1
LANG:C++
TASK:lamps
*/
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;int n,c,b[7],x;
bool fd;
const bool a[8][7]=
{0,0,0,0,0,0,0,
0,0,0,1,1,1,0,
0,0,1,0,1,0,1,
0,0,1,1,0,1,1,
0,1,0,0,1,0,0,
0,1,0,1,0,1,0,
0,1,1,0,0,0,1,
0,1,1,1,1,1,1};
inline char Getchar()
{
static char buf[100000],*p1=buf+100000,*pend=buf+100000;
if(p1==pend)
{
p1=buf; pend=buf+fread(buf,1,100000,stdin);
if (pend==p1) return -1;
}
return *p1++;
}
inline int read()
{
char c;int d=1,f=0;
while(c=Getchar(),!isdigit(c))if(c==45)d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=Getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void write(register long long x)
{
if(x<0)write(45),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
return;
}
inline void pd(register int x)
{
for(register int i=1;i<7;i++) if(b[i]!=-1&&a[x][i]!=b[i]) return;//不符合
for(register int i=1;i<=n;i++) write(a[x][(i-1)%6+1]);//符合即輸出
putchar(10);fd=true;return;
}
signed main()
{
fd=false;
fill(b+1,b+7,-1);
n=read();c=read();
while(x=read(),x!=-1) b[(x-1)%6+1]=1;
while(x=read(),x!=-1) b[(x-1)%6+1]=0;//初始化
if(!c)pd(7);else//不知在做處理
if(c==1){pd(0);pd(2);pd(3);pd(5);}else//1234四種操作
if(c==2){for(register int i=0;i<8;i++)if(i!=3)pd(i);}else//不作第四種操作
for(register int i=0;i<8;i++) pd(i);//所有操作
if(!fd) puts("IMPOSSIBLE");//沒找到
}