POJ2965-The Pilots Brothers' refrigerator
转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299077378
提示:这题和POJ1753翻转棋的思想是一致的,需要注意的是要求输出翻转过程,因此不能用BFS,必须用DFS(找到目标后,还要过程回溯)
与POJ1753相比,这题还要注意翻棋的方法,若不注意会大大浪费时间导致超时,因为是整行整列翻转,在边界处会出现很多多余操作。代码中详细说明
同样本题有两种方法,Enum和Bit ,下面分别贴出这两种代码
1 /*代码一:DFS+Enum*/
2
3
4
5 //Memory Time
6 //240K 641MS
7
8 //本题由于要输出每次翻转的棋子,因此不适宜用BFS,应该使用DFS输出完整路径
9
10 #include<iostream>
11 using namespace std;
12
13 bool lock[10][10]={false};
14 bool flag;
15 int step;
16 int ri[16],cj[16];
17
18 bool isopen(void)
19 {
20 for(int i=3;i<7;i++)
21 for(int j=3;j<7;j++)
22 if(lock[i][j]!=true)
23 return false;
24 return true;
25 }
26
27 void flip(int row,int col) //其实参考POJ1753的翻棋方法也是可以做出来的,但是会超时不通过
28 { //超时的原因就是翻棋时有太多多余的操作
29 lock[row][col]=!lock[row][col]; //POJ1753使用6x6矩形,多余操作只有周围的“一圈”翻棋!
30 for(int i=3;i<=6;i++) //这里使用10x10矩形,多余操作有“三圈”翻棋!
31 lock[i][col]=!lock[i][col]; //其实用位运算就可以只使用4x4矩形,大大降低时间复杂度,根本没有多余操作,但是程序会很复杂,不好看
32 for(int j=3;j<=6;j++)
33 lock[row][j]=!lock[row][j];
34 return;
35 }
36
37 void dfs(int row,int col,int deep)
38 {
39 if(deep==step)
40 {
41 flag=isopen();
42 return;
43 }
44
45 if(flag||row==7)return;
46
47 flip(row,col);
48 ri[deep]=row;
49 cj[deep]=col;
50
51 if(col<6)
52 dfs(row,col+1,deep+1);
53 else
54 dfs(row+1,3,deep+1);
55
56 flip(row,col);
57 if(col<6)
58 dfs(row,col+1,deep);
59 else
60 dfs(row+1,3,deep);
61 return;
62 }
63
64 int main(void)
65 {
66 char temp;
67 int i,j;
68 for(i=3;i<7;i++)
69 for(j=3;j<7;j++)
70 {
71 cin>>temp;
72 if(temp=='-')
73 lock[i][j]=true;
74 }
75
76 for(step=0;step<=16;step++)
77 {
78 dfs(3,3,0);
79 if(flag)break;
80 }
81
82 cout<<step<<endl;
83 for(i=0;i<step;i++)
84 cout<<ri[i]-2<<' '<<cj[i]-2<<endl;
85 return 0;
86 }
=============华丽的分割线=============
1 /*代码二:DFS+Bit*/
2
3 //Memory Time
4 //240K 563MS
5
6 //本题由于要输出每次翻转的棋子,因此不适宜用BFS,应该使用DFS输出完整路径
7
8 #include<iostream>
9 using namespace std;
10
11 int chess; //棋盘状态
12 int step;
13 bool flag=false;
14 int ri[16],cj[16];
15
16 bool isopen(void)
17 {
18 if(chess==0xFFFF)
19 return true;
20 else
21 return false;
22 }
23
24 void flip(int bit)
25 {
26 chess=chess^(0x1<<bit); //对翻转位取反
27 int row=bit/4;
28 int col=bit%4;
29 for(int c=0;c<4;c++)
30 chess=chess^(0x1<<(row*4+c)); //对全行取反
31 for(int r=0;r<4;r++)
32 chess=chess^(0x1<<(r*4+col)); //对全列取反
33 return;
34 }
35
36 void dfs(int bit,int deep)
37 {
38 if(deep==step)
39 {
40 flag=isopen();
41 return;
42 }
43
44 if(flag||bit>15)return;
45
46 int row=ri[deep]=bit/4;
47 int col=cj[deep]=bit%4;
48
49 flip(bit);
50 if(col<4)
51 dfs(bit+1,deep+1);
52 else
53 dfs((bit+4)/4*4,deep+1);
54
55 flip(bit);
56 if(col<4)
57 dfs(bit+1,deep);
58 else
59 dfs((bit+4)/4*4,deep);
60 return;
61 }
62
63 int main(void)
64 {
65 /*Input initial state*/
66
67 char temp;
68 int i,j;
69 for(i=0;i<4;i++)
70 for(j=0;j<4;j++)
71 {
72 cin>>temp;
73 if(temp=='-')
74 chess=chess^(0x1<<(i*4+j));
75 }
76
77 /*DFS*/
78
79 for(step=0;step<=16;step++)
80 {
81 dfs(0,0);
82 if(flag)
83 break;
84 }
85
86 cout<<step<<endl;
87 for(i=0;i<step;i++)
88 cout<<ri[i]+1<<' '<<cj[i]+1<<endl;
89 return 0;
90 }
[ EXP技术分享博客 ] 版权所有,转载请注明出处: http://exp-blog.com