题意:1753:关灯游戏,求使得画面全是同一个颜色为止的最小步数。
2965:仍然是4*4的方格,对某点的操作为对该点所在行和所在列全部翻转,问最小部数并输出方案。
思路:bfs+位运算。注意:棋盘一共有16个位置,每个位置最多翻转一次,所以搜索空间最大为2^16。每一种状态可以用一个数字表示。
2965:同前,队列里多记录一些信息即可。
1753代码:
#include <stdio.h> #include <string.h> char begin[5][5]; int q[1<<16],hash[1<<16];//hash标记下标状态是否被搜到过 int s; int change(int pos,int x){ int op = 0; if(x/4)//翻转处不在第一行 op |= (1<<(19-x)); if(x<12)//翻转处不在第四行 op |= (1<<(11-x)); if(x%4!=0)//翻转处不在最左列 op |= (1<<(16-x)); if(x%4!=3)//翻转处不在最右列 op |= (1<<(14-x)); op |= (1<<(15-x)); return pos ^= op; } int bfs(){ int i,front,rear; front = rear = -1; q[++rear] = s; while(front < rear){ int pos = q[++front]; for(i = 0;i<16;i++){//依次翻转16个位置 int temp = change(pos,i); if(!temp || temp==65535) return hash[pos]; if(!hash[temp]){ hash[temp] = hash[pos]+1; q[++rear] = temp; } } } return 0; } int main(){ int i,j; freopen("a.txt","r",stdin); memset(hash,0,sizeof(hash)); for(i = 0;i<4;i++) scanf("%s",begin[i]); for(i = 0;i<4;i++) for(j = 0;j<4;j++){ s <<= 1; if(begin[i][j] == 'b') s |= 1; } if(!s || s==65535)//一开始就是完好状态,特殊判断 printf("0\n"); else{ hash[s] = 1; i = bfs(); if(i) printf("%d\n",i); else printf("Impossible\n"); } return 0; }
2965代码:
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <cstdlib> using namespace std; #define clc(s,t) memset(s,t,sizeof(s)) #define INF 0x3fffffff int state; int flag[(1<<16)+5]; struct node{ int x,y,d,p,t; }q[(1<<16)+5]; int change(int s,int x){ int i,j,op = 0; j = x/4; for(i = j*4;i<j*4+4;i++) //每行 op |= (1<<i); j = x%4; for(i = j;i<16;i+=4) //每列 op |= (1<<i); return s^op; //进行翻转 } int bfs(){ int i,j,front,rear; struct node now; front = -1; rear = 0; while(front < rear){ now = q[++front]; if(now.t == (1<<16)-1) //找到目标状态,即16位全部为1 return front; for(i = 0;i<16;i++){ j = change(now.t,i);//变换后的新状态 if(!flag[j]){ q[++rear].t = j; q[rear].x = i/4; q[rear].y = i%4; q[rear].p = front; q[rear].d = now.d+1; flag[j] = 1; } } } return -1; } int main(){ int i,j; char ch; clc(flag, 0); state = 0; for(i = 0;i<4;i++){ for(j = 0;j<4;j++){ ch = getchar(); if(ch == '-') state |= (1<<(i*4+j)); } getchar(); } q[0].d = 0; q[0].p = -1; q[0].t = state; flag[state] = 1; j = bfs(); printf("%d\n",q[j].d); while(q[j].p!=-1){ printf("%d %d\n",q[j].x+1,q[j].y+1); j = q[j].p; } }