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\n",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\n",i+1,j+1); 68 } 69 } 70 }
一种高效算法,这种算法只对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 }
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\n", 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 }
poj2965 The Pilots Brothers' refrigerator 枚举或DFS
时间: 2024-10-05 11:36:40