题意: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;
}
}