第一次接触 状态压缩类的题刚开始的话,完全没有思路也没有想到位运算,然后就各种gg,
废话不说了 直接上代码吧。
POJ 1753;
题意就是翻棋子,求使棋盘上的棋子都是白棋或者黑棋,因为只有16个格子int的范围还能容下1<<16所以就用一个数来表示当前的状态就可以了。这里有个小技巧,就是读入的时候一重循环16如果是黑色(这里以黑色为1,白色为0)开始的状态就j加1<<i。然后bfs就可以了,记得要判断边界条件。
补充一下位运算
如果要获得第i位的数据,判断((data&(0X1<<i))==0),若真,为0,假,为1;
如果要设置第i位为1,data=(data|(0X1<<i));
如果要设置第i位为0,data=(data&(~(0X1<<i)));
如果要将第i位取反,data=(data^(0X1<<i);
如果要取出一个数的最后一个1(lowbit):(data&(-data)) (这里利用的是负数取反加1实际上改变的是二进制最低位的1如果要获得第i位的数据,判断((data&(0X1<<i))==0),若真,为0,假,为1;
如果要设置第i位为1,data=(data|(0X1<<i));
如果要设置第i位为0,data=(data&(~(0X1<<i)));
如果要将第i位取反,data=(data^(0X1<<i);
如果要取出一个数的最后一个1(lowbit):(data&(-data)) (这里利用的是负数取反加1实际上改变的是二进制最低位的1这个性质
#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node
{
int date;
int step;
};
bool book[65536],flag=0;
int bfs(int st)
{
memset(book,0,sizeof(book));
struct node head,tail;
head.date=st; head.step=0;
book[st]=1;
queue<node> que;
que.push(head);
while(!que.empty())
{
head=que.front();
que.pop();
if(head.date==0||head.date==65535)
{
printf("%d\n",head.step);
return 1;
}
for(int i=0;i<16;i++)
{
tail.date=head.date^(1<<i);
if(i%4)
{
tail.date=tail.date^(1<<(i-1));
}
if(i>3)
{
tail.date=tail.date^(1<<(i-4));
}
if(i<12)
{
tail.date=tail.date^(1<<(i+4));
}
if((i+1)%4)
{
tail.date=tail.date^(1<<(i+1));
}
if(!book[tail.date])
{
tail.step=head.step+1;
book[tail.date]=1;
que.push(tail);
}
}
}
return 0;
}
int main()
{
int st=0;
for(int i=0;i<16;i++)
{
char c;
scanf(" %c",&c);
if(c=='b')
{
st+=1<<i;
}
}
flag=bfs(st);
if(flag==0) printf("Impossible\n");
return 0;
}
#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
char map[120][120];
struct node
{
int x,y,snake,step,keys;
bool friend operator <(const node &a,const node & b)
{
return a.step>b.step;
}
};
bool vis[120][120][10][(1<<5)+5];
int dir[4][2]={0,1,0,-1 ,1,0 ,-1,0};
int n,k;
int sx,sy,ex,ey;
int book[120][120];
bool check(int x,int y)
{
if(x<=0||y<=0||x>n||y>n) return 0;
return 1;
}
int bfs()
{
struct node head,tail;
head.x=sx;head.y=sy;head.step=0;head.keys=0;head.snake=0;
vis[sx][sy][0][0]=1;
priority_queue<node> que;
que.push(head);
while(!que.empty())
{
head=que.top();
que.pop();
if(head.x==ex&&head.y==ey&&head.keys==k)
{
return head.step;
}
for(int i=0;i<4;i++)
{
tail.x=head.x+dir[i][0];
tail.y=head.y+dir[i][1];
tail.snake=head.snake;
tail.step=head.step+1;
tail.keys=head.keys;
if(check(tail.x,tail.y)&&!vis[tail.x][tail.y][tail.keys][tail.snake]&&map[tail.x][tail.y]!='#')
{
int key=map[tail.x][tail.y]-'0';
if(tail.keys+1==key)
{
tail.keys+=1;
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
else if(map[tail.x][tail.y]=='S')
{
if(tail.snake&(1<<book[tail.x][tail.y]))
{
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
else
{
tail.snake+=1<<book[tail.x][tail.y];
tail.step++;
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
}
else
{
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0) break;
memset(vis,0,sizeof(vis));
int cnt=0,ans=-1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf(" %c",&map[i][j]);
if(map[i][j]=='T') {ex=i;ey=j;}
else if(map[i][j]=='K') {sx=i;sy=j;}
else if(map[i][j]=='S') { book[i][j]=cnt++;}
}
}
ans=bfs();
if(ans!=-1) printf("%d\n",ans);
else printf("impossible\n");
}
return 0;
}
#include <iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
char map[120][120];
struct node
{
int x,y,snake,step,keys;
bool friend operator <(const node &a,const node & b)
{
return a.step>b.step;
}
};
bool vis[120][120][10][(1<<5)+5];
int dir[4][2]={0,1,0,-1 ,1,0 ,-1,0};
int n,k;
int sx,sy,ex,ey;
int book[120][120];
bool check(int x,int y)
{
if(x<=0||y<=0||x>n||y>n) return 0;
return 1;
}
int bfs()
{
struct node head,tail;
head.x=sx;head.y=sy;head.step=0;head.keys=0;head.snake=0;
vis[sx][sy][0][0]=1;
priority_queue<node> que;
que.push(head);
while(!que.empty())
{
head=que.top();
que.pop();
if(head.x==ex&&head.y==ey&&head.keys==k)
{
return head.step;
}
for(int i=0;i<4;i++)
{
tail.x=head.x+dir[i][0];
tail.y=head.y+dir[i][1];
tail.snake=head.snake;
tail.step=head.step+1;
tail.keys=head.keys;
if(check(tail.x,tail.y)&&!vis[tail.x][tail.y][tail.keys][tail.snake]&&map[tail.x][tail.y]!='#')
{
int key=map[tail.x][tail.y]-'0';
if(tail.keys+1==key)
{
tail.keys+=1;
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
else if(map[tail.x][tail.y]=='S')
{
if(tail.snake&(1<<book[tail.x][tail.y]))
{
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
else
{
tail.snake+=1<<book[tail.x][tail.y];
tail.step++;
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
}
else
{
vis[tail.x][tail.y][tail.keys][tail.snake]=1;
que.push(tail);
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
if(n==0&&k==0) break;
memset(vis,0,sizeof(vis));
int cnt=0,ans=-1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf(" %c",&map[i][j]);
if(map[i][j]=='T') {ex=i;ey=j;}
else if(map[i][j]=='K') {sx=i;sy=j;}
else if(map[i][j]=='S') { book[i][j]=cnt++;}
}
}
ans=bfs();
if(ans!=-1) printf("%d\n",ans);
else printf("impossible\n");
}
return 0;
}