[USACO2.2]派对灯 Party Lamps

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/84887212

链接

洛谷
USACO


大意

n n 盏灯

给定如下的变化方式

  1. 所有灯取反 [ 1 , 2 , 3 , 4 , 5... ] [1,2,3,4,5...]
  2. 所有奇数灯取反 [ 1 , 3 , 5 , 7 , 9... ] [1,3,5,7,9...]
  3. 所有偶数灯取反 [ 2 , 4 , 6 , 8 , 10... ] [2,4,6,8,10...]
  4. 所有 3 x + 1 ( x 0 ) [ 1 , 4 , 7 , 10 , 13... ] 3x+1(x\geq 0)[1,4,7,10,13...] 灯取反

给定最终状态的部分灯的亮灭情况
假设一开始所有灯都是亮着的,求出在 C C 步内可能达到与给定状态部分对应相等的所有状态

数据范围:
10 n 100 , C 1000 10\leq n\leq 100,C\leq 1000


思路

首先( F i r s t First ),一个灯按两次等于没按,按三次还不如按一次=所有方式至多选1次

接着( T h e n Then ),23方式的组合是等于1的,所有只有可能123分于4综合使用=多出三种变换方式,14,24,34

然后( N e x t Next ),第一种操作在所有范围内都会被影响,23操作两个两个一组被影响,4操作三个三个一组被影响, l c m ( 1 , 2 , 3 ) = 6 \because lcm(1,2,3)=6\therefore 每六个数所受的影响相同=答案六个一组循环

最后( F i n a l l y Finally ),注意我也可以不做处理!

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");//没找到
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/84887212
今日推荐