SRM 504(2-1000pt)

DIV2 1000pt

题意:对于一个n*m的矩阵,每个格子都有一个颜色B或者W。对矩阵A执行以下程序后变成矩阵B。给出矩阵B,求A。(若有多种情况,输出字典序最小的)。(n,m <= 16)

 1 For i = 0 to H-2:
 2     For j = 0 to W-2:
 3         //Get the current colors of cells (i,j) and (i,j+1)
 4         A = Color(i,j) , B = Color(i,j+1)
 5 
 6         If (A,B) == (White, White) Then:
 7              Do nothing.
 8         EndIf
 9         If (A,B) == (Black, White) Then: 
10              Repaint cells (i+1,j) and (i+1,j+1) Black.
11         EndIf
12         If (A,B) == (White, Black) Then:
13              Repaint cells (i+1,j) and (i+1,j+1) White.
14         EndIf
15         if (A,B) == (Black, Black) Then:
16              Swap the colors in cells (i+1,j) and (i+1,j+1).
17         EndIf
18     EndFor
19 EndFor
View Code

解法:

   法一,水解:首先注意到两点,一是在读取矩阵A的第i行的时候,对其第i+1行进行操作,二是矩阵A和矩阵B的第一行必然相同。

   所以,直接暴力DFS即可。由于每行最多只有16个,所以可以压缩状态来做。

   法二:比较考查思维的方法。首先仍然要注意到,读第i行时处理第i+1行,所以每行可以单独分析。其次,在读i处理i+1行时,有两种操作,对i+1行的某两个格子染色或者交换他们的颜色。若在读i行时对i+1行的某两个格子染色,则他们之前(在A矩阵中的时候)是什么颜色就不影响了,考虑到要字典序最小,所以应该让他们颜色为'B'。而其他没有被染色的格子,他们需要与变换后的位置的相应元素相同。

   这样的方法很巧,而且倒着写比较好写。

tag:think, good

法一:

 

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "Algrid.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define CLR(x) memset(x, 0, sizeof(x))
 38 #define CLR1(x) memset(x, -1, sizeof(x))
 39 #define PB push_back
 40 #define SZ(v) ((int)(v).size())
 41 #define zero(x) (((x)>0?(x):-(x))<eps)
 42 #define out(x) cout<<#x<<":"<<(x)<<endl
 43 #define tst(a) cout<<#a<<endl
 44 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 45 
 46 typedef vector<int> VI;
 47 typedef vector<string> VS;
 48 typedef vector<double> VD;
 49 typedef long long int64;
 50 
 51 const double eps = 1e-8;
 52 const double PI = atan(1.0)*4;
 53 const int maxint = 2139062143;
 54 
 55 int n, all, len;
 56 bool flag;
 57 int a[100], ans[100];
 58 
 59 int change(int x, int y)
 60 {
 61     if (x == -1) return -1;
 62 
 63     int ta[50], tb[50];
 64     int idxa = 0, idxb = 0;
 65     for (int i = 0; i < len; ++ i){
 66         ta[idxa++] = x & 1;
 67         x >>= 1;
 68         tb[idxb++] = y & 1;
 69         y >>= 1;
 70     }
 71     for (int i = len-1; i; -- i){
 72         if (!ta[i] && ta[i-1]) tb[i] = tb[i-1] = 0;
 73         if (ta[i] && !ta[i-1]) tb[i] = tb[i-1] = 1;
 74         if (!ta[i] && !ta[i-1]) swap(tb[i], tb[i-1]);
 75     }
 76     int ret = 0;
 77     for (int i = len-1; i >= 0; -- i)
 78         ret += (tb[i] << i);
 79     return ret;
 80 }
 81 
 82 void DFS (int x)
 83 {
 84     if (x == n){
 85         flag = 1;
 86         return;
 87     }
 88 
 89     for (int i = 0; i < all; ++ i)
 90         if (!flag && change(a[x-1], i) == a[x]){
 91             ans[x] = i;
 92             DFS (x+1);
 93             if (!flag) ans[x] = -1;
 94         }
 95 }
 96 
 97 class Algrid
 98 {
 99     public:
100         vector <string> makeProgram(vector <string> A){
101             len = A[0].size();
102             n = A.size(); all = 1 << len;
103             for (int i = 0; i < n; ++ i){
104                 int tmp = 0;
105                 for (int j = len-1, k = 0; j >= 0; -- j, ++ k)
106                     if (A[i][j] == 'W'){
107                         tmp += (1 << k);
108                     }
109                 a[i] = tmp;
110             }
111 
112             CLR1 (ans);
113             ans[0] = a[0];
114 
115             flag = 0;
116             DFS (1);
117 
118             vector<string> ret; ret.clear();
119             string tmp;
120             for (int i = 0; i < n; ++ i){
121                 if (ans[i] == -1){
122                     ret.clear(); return ret;
123                 }
124 
125                 tmp.clear();
126                 for (int j = len-1; j >= 0; -- j){
127                     if (ans[i] & (1<<j)) tmp.PB ('W');
128                     else tmp.PB('B');
129                 }
130                 ret.PB (tmp);
131             }
132             return ret;
133         }
134         
135 // BEGIN CUT HERE
136     public:
137     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
138     //void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0();}
139     private:
140     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
141     void verify_case(int Case, const vector <string> &Expected, const vector <string> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } }
142     void test_case_0() { string Arr0[] = {"WWBBB", "WBBBW"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"WWWWWWW", "WWWWWWB", "BBBBBBB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(0, Arg1, makeProgram(Arg0)); }
143     void test_case_1() { string Arr0[] = {"BBBBB",
144  "WBWBW"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"BBBBB", "WWBWB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(1, Arg1, makeProgram(Arg0)); }
145     void test_case_2() { string Arr0[] = {"BBBB",
146  "BBBB",
147  "BBWB",
148  "WWBB",
149  "BWBB"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = { }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(2, Arg1, makeProgram(Arg0)); }
150     void test_case_3() { string Arr0[] = {"WWBBBBW",
151  "BWBBWBB",
152  "BWBBWBW",
153  "BWWBWBB"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"WWBBBBW", "BBBBBWB", "BBBBBBB", "BBBWBBB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(3, Arg1, makeProgram(Arg0)); }
154 
155 // END CUT HERE
156 
157 };
158 
159 // BEGIN CUT HERE
160 int main()
161 {
162 //    freopen( "a.out" , "w" , stdout );    
163     Algrid ___test;
164     ___test.run_test(-1);
165        return 0;
166 }
167 // END CUT HERE
View Code

 

法二:

  1 // BEGIN CUT HERE
  2 /*
  3  * Author:  plum rain
  4  * score :
  5  */
  6 /*
  7 
  8  */
  9 // END CUT HERE
 10 #line 11 "Algrid.cpp"
 11 #include <sstream>
 12 #include <stdexcept>
 13 #include <functional>
 14 #include <iomanip>
 15 #include <numeric>
 16 #include <fstream>
 17 #include <cctype>
 18 #include <iostream>
 19 #include <cstdio>
 20 #include <vector>
 21 #include <cstring>
 22 #include <cmath>
 23 #include <algorithm>
 24 #include <cstdlib>
 25 #include <set>
 26 #include <queue>
 27 #include <bitset>
 28 #include <list>
 29 #include <string>
 30 #include <utility>
 31 #include <map>
 32 #include <ctime>
 33 #include <stack>
 34 
 35 using namespace std;
 36 
 37 #define CLR(x) memset(x, 0, sizeof(x))
 38 #define CLR1(x) memset(x, -1, sizeof(x))
 39 #define PB push_back
 40 #define SZ(v) ((int)(v).size())
 41 #define zero(x) (((x)>0?(x):-(x))<eps)
 42 #define out(x) cout<<#x<<":"<<(x)<<endl
 43 #define tst(a) cout<<#a<<endl
 44 #define CINBEQUICKER std::ios::sync_with_stdio(false)
 45 
 46 typedef vector<int> VI;
 47 typedef vector<string> VS;
 48 typedef vector<double> VD;
 49 typedef long long int64;
 50 
 51 const double eps = 1e-8;
 52 const double PI = atan(1.0)*4;
 53 const int maxint = 2139062143;
 54 
 55 class Algrid
 56 {
 57     public:
 58         vector <string> makeProgram(vector <string> opt){
 59             vector<string> tmp; tmp.clear();
 60             int n = opt.size(), m = opt[0].size();
 61             for (int i = n-2; i >= 0; -- i){
 62                 for (int j = m-2; j >= 0; -- j){
 63                     char a = opt[i][j], b = opt[i][j+1];
 64                     char &c = opt[i+1][j], &d = opt[i+1][j+1];
 65 
 66                     if (a == 'B' && b == 'B')
 67                         swap (c, d);
 68                     if (a == 'B' && b == 'W'){
 69                         if (c == 'W' || d == 'W') return tmp;
 70                         else d = c = '?';
 71                     }
 72                     if (a == 'W' && b == 'B'){
 73                         if (c == 'B' || d == 'B') return tmp;
 74                         else c = d = '?';
 75                     }
 76                 }
 77                 replace (opt[i+1].begin(), opt[i+1].end(), '?', 'B');
 78             }
 79             return opt;
 80         }
 81         
 82 // BEGIN CUT HERE
 83     public:
 84     void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
 85     private:
 86     template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
 87     void verify_case(int Case, const vector <string> &Expected, const vector <string> &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: " << print_array(Expected) << endl; cerr << "\tReceived: " << print_array(Received) << endl; } }
 88     void test_case_0() { string Arr0[] = {"WWWWWWW",
 89  "WWWWWWB",
 90  "BBBBBWW"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"WWWWWWW", "WWWWWWB", "BBBBBBB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(0, Arg1, makeProgram(Arg0)); }
 91     void test_case_1() { string Arr0[] = {"BBBBB",
 92  "WBWBW"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"BBBBB", "WWBWB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(1, Arg1, makeProgram(Arg0)); }
 93     void test_case_2() { string Arr0[] = {"BBBB",
 94  "BBBB",
 95  "BBWB",
 96  "WWBB",
 97  "BWBB"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = { }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(2, Arg1, makeProgram(Arg0)); }
 98     void test_case_3() { string Arr0[] = {"WWBBBBW",
 99  "BWBBWBB",
100  "BWBBWBW",
101  "BWWBWBB"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); string Arr1[] = {"WWBBBBW", "BBBBBWB", "BBBBBBB", "BBBWBBB" }; vector <string> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); verify_case(3, Arg1, makeProgram(Arg0)); }
102 
103 // END CUT HERE
104 
105 };
106 
107 // BEGIN CUT HERE
108 int main()
109 {
110 //    freopen( "a.out" , "w" , stdout );    
111     Algrid ___test;
112     ___test.run_test(-1);
113        return 0;
114 }
115 // END CUT HERE
View Code

 

 

posted @ 2013-12-09 23:51  Plumrain  阅读(214)  评论(0编辑  收藏  举报