~题目链接~
http://poj.org/problem?id=2965
输入
-+-- ---- ---- -+--
结果
6 1 1 1 3 1 4 4 1 4 3 4 4
1.BFS+位运算
自己写了一半天异或的代码,又长又不实用,提交还TLE(此在代码有 已被注释,如果有大牛可以改出来,希望帮助);后跟人家学了一招,很方便。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#define maxm 65535+10
#define maxn 4
using namespace std;
int ID[30] = {4383,8751,17487,34959,4593,8946,17652,35064,7953,12066,20292,36744,61713,61986,62532,63624};
int id=0,m=0,vis[1<<17];
struct node
{
int data,num,step;
} cur;
struct path
{
int x,pre;
}p[maxm<<2];
void f(int n)
{
if(n)
{
f(p[n].pre);
printf("%d %d\n",4-p[n].x/4,4-p[n].x%4);
}
}
void BFS()
{
int i;
cur.data=id;
cur.num=0;
cur.step=0;
p[1].pre=0;
queue<node>Q;
Q.push(cur);
while(!Q.empty())
{
if(Q.front().data==0)
{
printf("%d\n",Q.front().step);
f(Q.front().num);
return;
}
for(i=15; i>=0; i--)
{
node a;
//提交TLE的码码,有大牛在的话,求指教
/*int j;
a.data=Q.front().data^(1<<i);//此位点翻转
j=i;
while(j<12)//此位点列翻转
{
a.data^=1<<(j+4);
j+=4;
}
j=i;
while(j>=4)
{
a.data^=1<<(j-4);
j-=4;
}
j=i;
while(j%4)//此位点行翻转
{
a.data^=1<<(j-1);
j--;
}
j=i;
while((j+1)%4)
{
a.data^=1<<(j+1);
j++;
}//上面写的异或的代码很长而且提交TLE*/
a.data=Q.front().data^ID[i];//异或
if(!vis[a.data])
{
a.num=++m;
a.step=Q.front().step+1;
p[m].pre=Q.front().num;//存点,以便路径回溯
p[m].x=i;
Q.push(a);
vis[a.data]=1;
}
}
Q.pop();
}
}
int main()
{
char s[maxn];
for(int i=0; i<maxn; i++)
{
scanf("%s",s);
for(int j=0; j<maxn; j++)
{
id*=2;
if(s[j]=='+')
{
id+=1;
}
}
}
BFS();
return 0;
}
2.在POJ的讨论中看到大牛的一种高效方法之后写的代码
~大牛解题链接~ http://poj.org/showmessage?message_id=156561
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#define maxn 4
using namespace std;
int flag[maxn][maxn];
struct node
{
int x,y;
}N;
int main()
{
char s[maxn][maxn];
memset(flag,true,sizeof(flag));
for(int i=0; i<maxn; i++)
scanf("%s",s[i]);
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
if(s[i][j]=='+')
{
flag[i][j]=!flag[i][j];
for(int k=0; k<maxn; k++)
{
flag[k][j]=!flag[k][j];
flag[i][k]=!flag[i][k];
}
}
int num=0;
queue<struct node>Q;
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
if(!flag[i][j])
{
N.x=i;
N.y=j;
Q.push(N);
num++;
}
printf("%d\n",num);
while(!Q.empty())
{
printf("%d %d\n",Q.front().x+1,Q.front().y+1);
Q.pop();
}
return 0;
}