题目地址:http://poj.org/problem?id=2965
1 /*
2 题意:4*4的矩形,改变任意点,把所有'+'变成'-',,每一次同行同列的都会反转,求最小步数,并打印方案
3
4 DFS:把'+'记为1, '-'记为0
5 1. 从(1, 1)走到(4, 4),每一点DFS两次(改点反转或不反转);used记录反转的位置
6 详细解释:http://poj.org/showmessage?message_id=346723
7 2. 比较巧妙的解法:抓住'+'位置反转,'-'位置相对不反转的特点,从状态上考虑
8 详细解释:http://poj.org/showmessage?message_id=156561
9 3. 枚举步骤数(1~16),暴力解法,耗时大
10 详细解释:http://poj.org/showmessage?message_id=343281
11 4. 网上还有其他解法:高斯消元,BFS,+位运算等等
12
13 注意:反转时十字形中心位置多反转了两次,要再反转一次
14
15 我还是DFS写不出来。。。
16 */
17 #include <cstdio>
18 #include <iostream>
19 #include <algorithm>
20 #include <cstring>
21 #include <cmath>
22 #include <string>
23 #include <map>
24 #include <queue>
25 #include <vector>
26 using namespace std;
27
28 const int MAXN = 1e6 + 10;
29 const int INF = 0x3f3f3f3f;
30 int a[5][5];
31 int used[5][5];
32
33 bool ok(void)
34 {
35 for (int i=1; i<=4; ++i)
36 {
37 for (int j=1; j<=4; ++j)
38 if (a[i][j] == 1) return false;
39 }
40
41 return true;
42 }
43
44 void change(int x, int y)
45 {
46 for (int i=1; i<=4; ++i)
47 {
48 a[x][i] = a[x][i] ? 0 : 1;
49 a[i][y] = a[i][y] ? 0 : 1;
50 }
51 a[x][y] = a[x][y] ? 0 : 1;
52 used[x][y] = used[x][y] ? 0 : 1;
53 }
54
55 bool DFS(int x, int y)
56 {
57 if (x == 4 && y == 4)
58 {
59 if (ok ()) return true;
60
61 change (x, y);
62 if (ok ()) return true;
63
64 change (x, y);
65 return false;
66 }
67 int nx, ny;
68 if (y == 4) nx = x + 1, ny = 1;
69 else nx = x, ny = y + 1;
70
71 if (DFS (nx, ny)) return true;
72
73 change (x, y);
74 if (DFS (nx, ny)) return true;
75
76 change (x, y);
77 return false;
78 }
79
80 void work(void)
81 {
82 if (DFS (1, 1))
83 {
84 int ans = 0;
85 for (int i=1; i<=4; ++i)
86 {
87 for (int j=1; j<=4; ++j)
88 {
89 if (used[i][j]) ans++;
90 }
91 }
92 printf ("%d
", ans);
93 for (int i=1; i<=4; ++i)
94 for (int j=1; j<=4; ++j)
95 if (used[i][j]) printf ("%d %d
", i, j);
96 }
97 else printf ("WA
");
98 }
99
100 int main(void) //POJ 2965 The Pilots Brothers' refrigerator
101 {
102 //freopen ("B.in", "r", stdin);
103
104 char ch;
105 for (int i=1; i<=4; ++i)
106 {
107 for (int j=1; j<=4; ++j)
108 {
109 scanf ("%c", &ch);
110 a[i][j] = (ch == '-') ? 0 : 1;
111 //printf ("%d ", a[i][j]);
112 }
113 getchar (); //puts ("");
114 }
115
116 work ();
117
118 return 0;
119 }
120
121 /*
122 #include <cstdio>
123 #include <iostream>
124 #include <algorithm>
125 #include <cstring>
126 #include <cmath>
127 #include <string>
128 #include <map>
129 #include <queue>
130 #include <vector>
131 using namespace std;
132
133 const int MAXN = 1e6 + 10;
134 const int INF = 0x3f3f3f3f;
135 bool con[5][5];
136 int a[5][5];
137 struct NODE
138 {
139 int x, y;
140 }node[MAXN];
141
142 void work(void)
143 {
144 for (int i=1; i<=4; ++i)
145 {
146 for (int j=1; j<=4; ++j)
147 {
148 if (a[i][j] == 1)
149 {
150 con[i][j] = !con[i][j];
151 for (int k=1; k<=4; ++k)
152 {
153 con[i][k] = !con[i][k];
154 con[k][j] = !con[k][j];
155 }
156 }
157 }
158 }
159 int ans = 0;
160 for (int i=1; i<=4; ++i)
161 {
162 for (int j=1; j<=4; ++j)
163 {
164 if (con[i][j] == true)
165 {
166 ans++; node[ans].x = i; node[ans].y = j;
167 }
168 }
169 }
170 printf ("%d
", ans);
171 for (int i=1; i<=ans; ++i)
172 printf ("%d %d
", node[i].x, node[i].y);
173 }
174
175 int main(void) //POJ 2965 The Pilots Brothers' refrigerator
176 {
177 //freopen ("B.in", "r", stdin);
178
179 char ch;
180 for (int i=1; i<=4; ++i)
181 {
182 for (int j=1; j<=4; ++j)
183 {
184 scanf ("%c", &ch);
185 a[i][j] = (ch == '-') ? 0 : 1;
186 }
187 getchar ();
188 }
189
190 work ();
191
192 return 0;
193 }
194 */
195
196 /*
197 #include <cstdio>
198 #include <iostream>
199 #include <algorithm>
200 #include <cstring>
201 #include <cmath>
202 #include <string>
203 #include <map>
204 #include <queue>
205 #include <vector>
206 using namespace std;
207
208 const int MAXN = 1e6 + 10;
209 const int INF = 0x3f3f3f3f;
210 int a[5][5];
211 struct NODE
212 {
213 int x, y;
214 }node[MAXN];
215 int k;
216 bool flag;
217
218 bool ok(void)
219 {
220 for (int i=1; i<=4; ++i)
221 {
222 for (int j=1; j<=4; ++j)
223 if (a[i][j] == 1) return false;
224 }
225
226 return true;
227 }
228
229 void change(int x, int y)
230 {
231 for (int i=1; i<=4; ++i)
232 {
233 a[x][i] = !a[x][i];
234 a[i][y] = !a[i][y];
235 }
236 a[x][y] = !a[x][y];
237 }
238
239 void DFS(int x, int y, int num, int cnt, int kk)
240 {
241 if (num == cnt)
242 {
243 flag = ok ();
244 k = kk;
245 return ;
246 }
247 for (int i=x; i<=4; ++i)
248 {
249 int j;
250 if (i == x) j = y + 1;
251 else j = 1;
252 for (; j<=4; ++j)
253 {
254 node[kk].x = i;
255 node[kk].y = j;
256 change (i, j);
257 DFS (i, j, num+1, cnt, kk+1);
258 if (flag) return ;
259 change (i, j);
260 }
261 }
262 }
263
264 void work(void)
265 {
266 int cnt;
267 for (cnt=1; cnt<=16; ++cnt)
268 {
269 flag = false; k = 0;
270 DFS (1, 0, 0, cnt, 1);
271 if (flag) break;
272 }
273
274 printf ("%d
", cnt);
275 for (int i=1; i<=k - 1; ++i)
276 printf ("%d %d
", node[i].x, node[i].y);
277 }
278
279 int main(void) //POJ 2965 The Pilots Brothers' refrigerator
280 {
281 //freopen ("B.in", "r", stdin);
282
283 char ch;
284 for (int i=1; i<=4; ++i)
285 {
286 for (int j=1; j<=4; ++j)
287 {
288 scanf ("%c", &ch);
289 a[i][j] = (ch == '-') ? 0 : 1;
290 }
291 getchar ();
292 }
293
294 work ();
295
296 return 0;
297 }
298 */