POJ1753
来源:互联网 发布:mac给文件夹系统权限 编辑:程序博客网 时间:2024/06/04 18:33
------------------------
/*方法一:先算出所有状态对应的步数POJ1753首先需要明确:1.棋盘最多只能走16步,2^16=65536因此可以枚举来解题(其实每格棋子最多只可以翻转一次(实际是奇数次,但这没意义),只要其中一格重复翻了2次(不论是连续翻动还是不连翻动),那么它以及周边的棋子和没翻动时的状态是一致的,由此就可以确定这个棋盘最多只能走16步)2.每种状态可以转化为一个数,然后每次改变只要做对应的位操作。4*4的b,w可以看作16为0,1组成的数字。思路:3.step[x],x表示输入棋盘状态所对应的数字,step[x]表示步数4.0,65535是最终的状态,逆推求出只需要走一步的棋盘状态所对应的数:分别翻动第1~16位,tmp数组记录下这16个数,step[xi]=1,step[xi^65535]=1;别忘了全为b或者全为w都可以,如果x翻动一次就可以了,那x^65535也只要翻动1次就可以了。5.求出只需要走2步的棋盘状态所对应的数:在走1步的基础上再走1步,相当于相互异或(思考下为什么是异或~)6.求表示三步状态的数:把1步的跟2步的数异或,就是相当于在走了2步的基础上再走一步。(需要防止重复)7..以此类推,算出直至表示16步状态的数,改变step数组以他们为下标的值会发现有些数字转化为0,65535是需要一样的步数383,2287,4919,7128,29262,36046,58407,,,*/#include<cstdio>const int N=66536;bool vist[N];int step[N],tmp[N];int top=0;void Init_step1(){ int i,cur,cur_t; for(i=0;i<16;++i){ cur=cur_t=1<<i; if(i%4!=0) cur|=cur_t>>1; if((i+1)%4!=0) cur|=cur_t<<1; if(i-4>=0)cur|=cur_t>>4; if(i+4<16)cur|=cur_t<<4; if(!vist[cur]){ vist[cur]=true,vist[cur^65535]=true; tmp[top++]=cur; step[cur]=1,step[cur^65535]=1; // printf("----%d %d\ n",cur,cur^65535); } } vist[0]=vist[65535]=true;}void Init_step2_16(){ int stepp,ptr1,ptr2,pre,pre_top,cur; for(stepp=2,pre=0,pre_top=16;stepp<17;++stepp){ for(ptr2=pre;ptr2<pre_top;++ptr2){ for(ptr1=0;ptr1<16;++ptr1){ cur=tmp[ptr2]^tmp[ptr1]; if(!vist[cur]){ vist[cur]=true;vist[cur^65535]=true; tmp[top++]=cur; step[cur]=stepp; step[cur^65535]=stepp; } } } pre=pre_top; pre_top=top; printf("pre=%d pre_top=%d stepp=%d\n",pre,pre_top,stepp); }}int main(){ char str[5][5]; Init_step1(); Init_step2_16(); // printf("saass%d\n",step[38441]); int i,j,x,cnt; while(~scanf("%s",str[0])){ for(i=1;i<4;++i) scanf("%s",str[i]); for(i=0,cnt=15,x=0;i<4;++i) for(j=0;j<4;++j,--cnt)if(str[i][j]=='b')x|=1<<cnt; if(x==0||x==65535) printf("0\n"); else if(!step[x]) puts("Impossible"); else printf("%d\n",step[x]); }}
-----------------------------
-------------------------------
/*方法2:考虑所有可能,暴力求解。分别翻动1~16位,翻动次数从1到16若还没有解,则为不可能*/#include<cstdio>#include<cstring>const int N=66536;bool vist[N];int step[N],tmp[N];int top=1;int change(int i,int cur){ int cur_t; cur_t=1<<i;cur^=cur_t; if(i%4!=0) cur^=cur_t>>1; if((i+1)%4!=0) cur^=cur_t<<1; if(i-4>=0)cur^=cur_t>>4; if(i+4<16)cur^=cur_t<<4; return cur;}int calc_ans(int x){ int i,cur,pre,stepp,ptr1,st,ed; tmp[0]=x; vist[x]=true; for(stepp=1,st=0,ed=1;stepp<17;++stepp){ for(ptr1=st;ptr1<ed;++ptr1){ pre=tmp[ptr1]; for(i=0;i<16;++i){ cur=change(i,pre); if(cur==0||cur==65535)return stepp; if(!vist[cur]){ vist[cur]=true; tmp[top++]=cur; } } } st=ed;ed=top; } return -1;}int main(){ char str[5][5]; int i,j,x,cnt,ans=-1; while(~scanf("%s",str[0])){ memset(vist,0,sizeof(vist)); top=1; for(ans=-1,i=1;i<4;++i) scanf("%s",str[i]); for(i=0,cnt=15,x=0;i<4;++i) for(j=0;j<4;++j,--cnt)if(str[i][j]=='b')x|=1<<cnt; if(x==0||x==65535) printf("0\n"); else{ ans=calc_ans(x); if(ans<0) puts("Impossible"); else printf("%d\n",ans); } }}
0 0
- POJ1753
- poj1753
- poj1753
- poj1753
- POJ1753
- poj1753
- poj1753
- poj1753
- poj1753
- POJ1753
- POJ1753
- POJ1753
- POJ1753
- poj1753
- poj1753
- POJ1753
- poj1753
- poj1753
- 30天自制操作系统——用U盘启动自制系统
- Android 群发短信
- 编程实现以二进制形式系那是无符号整数
- 第13周项目4-(3)体验选择排序
- mmap系统调用
- POJ1753
- 异步编程学习-Twisted学习文档【未完成】
- Memcached与Spring AOP构建数分布式据库前端缓存框架
- 网站设计:将Footer固定在浏览器底部
- sql
- 通过 Shell 和 Expect 脚本实现对 IBM 刀片服务器高级管理模块固件的大量升级
- 第十三周项目6——1——3 又是成绩
- 特征选择算法之开方检验
- ubuntu快捷键