poj2965 The Pilots Brothers' refrigerator 枚举或DFS

http://poj.org/problem?id=2965

一、枚举每一个‘+’点,对该点和该点所在的同一行和同一列所有点进行操作,开关本身状态改变了7次,开关同一行、同一列的开关状态改变了4次,其他开关状态改变了2次。

然后,用一个数组存取每个操作,如果为奇数,则证明该点为必须点,否则为不必要的。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 char map[4][4];
 5 int ans[4][4];
 6 char as(char g)
 7 {
 8     if(g=='+')
 9     return '-';
10     return '+';
11 }
12 void qw(int n,int m)
13 {
14     for(int i=0;i<4;i++)
15     {
16         map[n][i]=as(map[n][i]);
17     }
18     for(int j=0;j<4;j++)
19     {
20         if(j!=n)
21         map[j][m]=as(map[j][m]);
22     }
23     ans[n][m]++;
24 }
25 void ac()
26 {
27     for(int i=0;i<4;i++)
28     {
29         for(int j=0;j<4;j++)
30         {
31             if(map[i][j]=='+')
32             {
33                 for(int t=0;t<4;t++)
34                 {
35                     qw(i,t);
36                 }
37                 for(int t=0;t<4;t++)
38                 {
39                     if(t!=i)
40                     qw(t,j);
41                 }
42             }
43         }
44     }
45 }
46 main()
47 {
48     int i,j,cas=0;
49     for(i=0;i<4;i++)
50     scanf("%s",map[i]);
51     memset(ans,0,sizeof(ans));
52     ac();
53     for(i=0;i<4;i++)
54     {
55         for(j=0;j<4;j++)
56         {
57             if(ans[i][j]%2==1)
58             cas++;
59         }
60     }
61     printf("%d
",cas);
62     for(i=0;i<4;i++)
63     {
64         for(j=0;j<4;j++)
65         {
66             if(ans[i][j]%2==1)
67             printf("%d %d
",i+1,j+1);
68         }
69     }
70 }
View Code

 一种高效算法,这种算法只对n为偶数时适用。

 1 #include<iostream>
 2 #include<memory.h>
 3 using namespace std;
 4 #define INF 0x7fffffff
 5 int p[5][5];
 6 int main(void)
 7 {
 8     char c;
 9     memset(p, 0, sizeof(p));
10     for (int i = 1; i <= 4; i++)
11         for (int j = 1; j <= 4; j++)
12         {
13             cin >> c;
14             if (c == '+')
15             {
16                 for (int k = 1; k <= 4; k++)
17                 {
18                     p[i][k]++;
19                     p[k][j]++;
20                 }
21                 p[i][j]--;
22             }
23         }
24     int sum = 0;
25     for (int i = 1; i <= 4; i++)
26         for (int j = 1; j <= 4; j++)
27             sum += p[i][j]%2;
28     cout << sum << endl;
29     for (int i = 1; i <= 4; i++)
30         for (int j = 1; j <= 4; j++)
31             if  (p[i][j]%2)
32                 cout << i << " " << j << endl;
33 //    system("pause");
34     return 0;
35 }
View Code
 

DFS版

  1 #include <iostream>
  2 
  3 #include <cstdio>
  4 
  5 #include <cstring>
  6 
  7 #include <cstdlib>
  8 
  9 using namespace std;
 10 
 11  
 12 
 13 bool map[4][4];
 14 
 15 int ans[16];
 16 
 17  
 18 
 19 void init()
 20 
 21 {
 22 
 23     int i, j;
 24 
 25  
 26 
 27     for (i = 0; i < 4; i++)
 28 
 29     {
 30 
 31         for (j = 0; j < 4; j++)
 32 
 33         {
 34 
 35             char ch;
 36 
 37             cin >> ch;
 38 
 39             if (ch == '-')
 40 
 41                 map[i][j] = true;
 42 
 43             else
 44 
 45                 map[i][j] = false;
 46 
 47         }
 48 
 49         getchar();
 50 
 51     }
 52 
 53 }
 54 
 55  
 56 
 57 void operate(int x, int y)
 58 
 59 {
 60 
 61     if (x < 0 || y < 0 || x > 3 || y > 3)
 62 
 63         return;
 64 
 65     map[x][y] = !map[x][y];
 66 
 67 }
 68 
 69  
 70 
 71 void turn(int pos)
 72 
 73 {
 74 
 75     ans[pos] = !ans[pos];
 76 
 77     int x = pos / 4;
 78 
 79     int y = pos % 4;
 80 
 81     int i;
 82 
 83     operate(x, y);
 84 
 85     for (i = 1; i < 4; i++)
 86 
 87     {
 88 
 89         operate(x + i, y);
 90 
 91         operate(x, y + i);
 92 
 93         operate(x - i, y);
 94 
 95         operate(x, y - i);
 96 
 97     }
 98 
 99 }
100 
101  
102 
103 bool finished()
104 
105 {
106 
107     int tot = 0;
108 
109     int i;
110 
111     for (i = 0; i < 16; i++)
112 
113         tot += map[i / 4][i % 4];
114 
115     return (tot == 16);
116 
117 }
118 
119  
120 
121 void output()
122 
123 {
124 
125     int i;
126 
127     for (i = 0; i < 16; i++)
128 
129     {
130 
131         if (ans[i])
132 
133             printf("%d %d
", i / 4 + 1, i % 4 + 1);
134 
135     }
136 
137 }
138 
139  
140 
141 void dfs(int pos, int step)
142 
143 {
144 
145     if (finished())
146 
147     {
148 
149         cout << step << endl;
150 
151         output();
152 
153 
154         return;
155 
156     }
157 
158     if (pos >= 16)
159 
160         return;
161 
162     dfs(pos + 1, step);
163 
164     turn(pos);
165 
166     dfs(pos + 1, step + 1);
167 
168     turn(pos);
169 
170 }
171 
172  
173 
174 int main()
175 
176 {
177 
178 
179     init();
180 
181     dfs(0, 0);
182 
183  
184 
185     return 0;
186 
187 }
View Code
原文地址:https://www.cnblogs.com/CrazyBaby/p/5506530.html