poj1753

#include<iostream>
using namespace std;
int board[4][4];
bool occurance[1<<16];
int root=0;
class Node{
public:
int status;
int step;
};
class Queue{
public:
Queue():rear(0),head(0){};
Node nodes[1<<16];
void push(Node& node);
void pop(Node& node);
bool isEmpty();
private:
int rear;
int head;
};
bool Queue::isEmpty(){
return rear<=head;
};
void Queue::push(Node& node){ 
nodes[rear].status=node.status;
nodes[rear].step=node.step;
rear++;  
};
void Queue::pop(Node& node){ 
node.status=nodes[head].status;
node.step=nodes[head].step;
head++;
};
void init(){ 
int tagValue=1;
for(int i=3;i>=0;i--){
for(int j=3;j>=0;j--){
board[i][j]=tagValue;
tagValue=tagValue<<1;
}
}


for(int i=0;i<1<<17;i++){
occurance[i]=0;
}


char x;
root=0;
for(int i=0;i<16;i++){
cin>>x;
root=root<<1;
if(x=='b')
root=root^1;
}
}


int main(){
init();
occurance[root]=1;
Node parent,temp;
Node* result;
parent.status=root;
parent.step=0;
Queue queue;
queue.push(parent);
int flag=0;
while(!queue.isEmpty()){
queue.pop(parent);
if(parent.status==0||parent.status==(65535)){
flag=1;
result=&parent;
break;
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
temp.status=parent.status^board[i][j];
temp.step=parent.step+1;
if(i-1>=0){
temp.status^=board[i-1][j];
}
if(i+1<=3){
temp.status^=board[i+1][j];
}
if(j-1>=0){
temp.status^=board[i][j-1];
}
if(j+1<=3){
temp.status^=board[i][j+1];
}
if(!occurance[temp.status]){
queue.push(temp);
occurance[temp.status]=1;
}
if(temp.status==0||temp.status==(65535)){
flag=1;
result=&temp;
break;
}

} 
}
if(flag==1)
break;
}
if(flag==1){
cout<<result->step<<endl;
}else{
cout<<"Impossible"<<endl;
}
return 0;
}



1. 遍历check结果就有多种做法

(1)
int v=a[0][0];
for(int i=0;i<16;i++)
if(v!=a[i][j])
return false;
(2)
int sum=0;
for(int i=0;i<16;i++)
sum+=a[i][j];
if(sum==0||sum==16)
return true;
return false;


2.自定义queue,省空间,好处多
3. 1,0变相反
(1)x^1

(2)x=1-x;

(3)x=!x;

4.int^1 只改变了二进制形式的最后一位。。
5.状态压缩
(1)单位在不同位置设01
(2)整体组成一个问题状态
(3)移位和异或
(4)状态是index
6.本题就是BFS,每一层就是一步,因为状态是有限个
,并且不允许重复,所以总可以结束。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值