TopCoder: SRM288 DIV2 1000

Problem Statement

    

You are given a 4x4 game board consisting of buttons which are either lit or unlit. The buttons are numbered 1-16, like so:

 1  2  3  4

 5  6  7  8

 9 10 11 12

13 14 15 16

Pressing a button changes the state of that button, along with the states of the buttons to the immediate left, right, top and bottom. Pressing and holding a button, which counts as two moves, changes only the state of that individual light.

The goal of the game is to turn off all of the lights. You are given a vector <string> board consisting of four elements, each containing four characters. Each character will be a '0' or '1', indicating whether each light is off or on, respectively. You are to return an int indicating the least number of moves necessary to turn off all of the lights.

Definition

    
Class: TurnOffLights
Method: fewestMoves
Parameters: vector <string>
Returns: int
Method signature: int fewestMoves(vector <string> board)
(be sure your method is public)
    
 

Constraints

- board will contain exactly 4 elements.
- Each element of board will contain exactly 4 characters.
- Each character of each element of board will be '0' (zero) or '1' (one).

Examples

0)  
    
{"1100",

 "1000",

 "0000",

 "0000"}
Returns: 1
Press only the button in the upper left corner.
1)  
    
{"0100",

 "1110",

 "0100",

 "0000"}
Returns: 1
Again, a single button press suffices.
2)  
    
{"1000",

 "0000",

 "0000",

 "0000"}
Returns: 2
We need to press and hold the lit button, which costs us two moves.
3)  
    
{"1100",

 "1000",

 "0000",

 "0001"}
Returns: 3
Press the upper left button (costs 1). Press and hold the lower right button (costs 2).
4)  
    
{"1011",

 "1010",

 "0000",

 "0000"}
Returns: 2
Here, we push buttons 1 and 3. Notice that button 2 lights up after the first button push, but ends up unlit at the end.

这题采用位运算+bfs, 16个格子的状态为0和1,这样可以用位来记录整个board,对board进行异或操作就是press操作,press数组记录了32种可能的操作,用visit数组来记录有没有访问过,如果有说明以前有到这个状态那么再回到这个状态需要的step是多余的,肯定不是最少的。

View Code
  1 // BEGIN CUT HERE

  2 

  3 // END CUT HERE

  4 #include <functional>

  5 #include <algorithm>

  6 #include <stdexcept>

  7 #include <iostream>

  8 #include <sstream>

  9 #include <fstream>

 10 #include <iomanip>

 11 #include <cstdlib>

 12 #include <cstring>

 13 #include <utility>

 14 #include <cctype>

 15 #include <vector>

 16 #include <string>

 17 #include <bitset>

 18 #include <queue>

 19 #include <stack>

 20 #include <ctime>

 21 #include <list>

 22 #include <map>

 23 #include <set>

 24 #include <cmath>

 25 

 26 using namespace std;

 27 

 28 #define pb push_back

 29 #define INF 100000000000

 30 #define L(s) (int)((s).size())

 31 #define FOR(i,a,b) for (int _n(b), i(a); i<=_n; i++)

 32 #define rep(i,n) FOR(i,1,(n))

 33 #define rept(i,n) FOR(i,0,(n)-1)

 34 #define C(a) memset((a), 0, sizeof(a))

 35 #define ll long long

 36 #define VI vector<int>

 37 #define ppb pop_back

 38 #define mp make_pair

 39 #define MOD 1000000007

 40 int toInt(string s){ istringstream sin(s); int t; sin>>t;return t;}

 41 

 42 int press[32] =

 43     {

 44         51200, 58368, 29184, 12544,

 45         35968, 20032, 10016, 4880,

 46         2248, 1252, 626, 305,

 47         140, 78, 39, 19,

 48         32768, 16384, 8192, 4096,

 49         2048, 1024, 512, 256,

 50         128, 64, 32, 16,

 51         8, 4, 2, 1

 52 };

 53 class TurnOffLights

 54 {

 55     bool visit[65536];

 56     struct Node {

 57         int state;

 58         int step;

 59     };

 60 

 61         public:

 62         int bfs(int state, int &ans)

 63         {

 64             C(visit);

 65             queue<Node> q;

 66             Node cur, next;

 67             cur.state = state;

 68             cur.step = 0;

 69             q.push(cur);

 70             visit[state] = true;

 71             while (!q.empty())

 72             {

 73                 cur = q.front();

 74                 q.pop();

 75                 if (cur.state == 0)

 76                 {

 77                     ans = min(ans, cur.step);

 78                     continue;

 79                 }

 80                 rept(i, 32)

 81                 {

 82                     next.state = cur.state ^ press[i];

 83                     next.step = cur.step + i/16 + 1;

 84                     if (visit[next.state])

 85                         continue;

 86                     if (next.state == 0)

 87                     {

 88                         ans = min(ans, next.step);

 89                         continue;

 90                     }

 91                     visit[next.state] = true;

 92                     q.push(next);

 93                 }

 94             }

 95             return ans;

 96         }

 97         int fewestMoves(vector <string> board)

 98         {

 99             int state, ans;

100             state = 0;

101             rept(i, 4)

102             {

103                 rept(j, 4)

104                 {

105                     state <<= 1;

106                     if (board[i][j] == '1')

107                         state += 1;

108                 }

109             }

110             ans = INT_MAX;

111             ans = bfs(state, ans);

112             return ans;

113         }

114 

115 // BEGIN CUT HERE

116     public:

117     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(); if ((Case == -1) || (Case == 4)) test_case_4(); }

118     private:

119     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(); }

120     void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }

121     void test_case_0() { string Arr0[] = {"1100",

122  "1000",

123  "0000",

124  "0000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(0, Arg1, fewestMoves(Arg0)); }

125     void test_case_1() { string Arr0[] = {"0100",

126  "1110",

127  "0100",

128  "0000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; verify_case(1, Arg1, fewestMoves(Arg0)); }

129     void test_case_2() { string Arr0[] = {"1000",

130  "0000",

131  "0000",

132  "0000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(2, Arg1, fewestMoves(Arg0)); }

133     void test_case_3() { string Arr0[] = {"1100",

134  "1000",

135  "0000",

136  "0001"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; verify_case(3, Arg1, fewestMoves(Arg0)); }

137     void test_case_4() { string Arr0[] = {"1011",

138  "1010",

139  "0000",

140  "0000"}; vector <string> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; verify_case(4, Arg1, fewestMoves(Arg0)); }

141 

142 // END CUT HERE

143 

144 };

145 // BEGIN CUT HERE

146 int main()

147 {

148         TurnOffLights ___test;

149         ___test.run_test(-1);

150         return 0;

151 }

152 // END CUT HERE

 

你可能感兴趣的:(topcoder)