hdu3278Puzzle

其实最终的结果无非是中间8个方块是相同的颜色,外面16个方块是另外两种颜色。那么其实可以把外面两种颜色看作是0,中间的颜色看做是1。

那么题目就变成了把那种颜色看做1,而其它两种颜色看做0,可以用最少的步骤得到结果。

那么24个方块就可以用24位二进制来标记。那么判重的方式找到了,映射为一个int类型的整数hash

而方块的移动可以看做是位运算的组合,慢慢想想就能够用位运算直接在整数hash上运算,而得到另一个整数。

  1 #include <stdio.h>

  2 #include <string.h>

  3 #include <string>

  4 #include <queue>

  5 #include <iostream>

  6 #include <map>

  7 using namespace std;

  8 int q[1<<24];

  9 short step[1<<24];

 10 /*

 11 0 1 2 3 4 5 --> 1 2 3 4 5 0

 12 0 1 2 3 4 5 --> 5 0 1 2 3 4

 13 6 7 8 9 10 11 ->7 8 9 19 11 6

 14 

 15 0 6 12 18 --> 6 12 18 0

 16 0 6 12 18 --> 18 0 6 12

 17 1 7 13 19 --> 7 13 19 1

 18 1 7 13 19 --> 19 1 7 13

 19 4

 20 */

 21 inline int min(const int&a, const int &b)

 22 {

 23     return a < b ? a : b;

 24 }

 25 int tmp[5],c;

 26 int inline col1(int k,int s)

 27 {

 28     c = -1;

 29     for(int i=0; i<4; i++)

 30     {

 31         c -= (1<<(i*6+k));

 32         tmp[i]=s&(1<<(i*6+k));

 33     }

 34     s=s&c;

 35     tmp[0]<<=18;

 36     tmp[1]>>=6;

 37     tmp[2]>>=6;

 38     tmp[3]>>=6;

 39     s=s+tmp[0]+tmp[1]+tmp[2]+tmp[3];

 40     return s;

 41 }

 42 int inline col2(int k,int s)

 43 {

 44     c = -1;

 45     for(int i=0; i<4; i++)

 46     {

 47         c -= (1<<(i*6+k));

 48         tmp[i]=s&(1<<(i*6+k));

 49     }

 50     s=s&c;

 51     tmp[0]<<=6;

 52     tmp[1]<<=6;

 53     tmp[2]<<=6;

 54     tmp[3]>>=18;

 55     s=s+tmp[0]+tmp[1]+tmp[2]+tmp[3];

 56     return s;

 57 }

 58 int inline row1(int k,int s)

 59 {

 60     c = 63<<(k*6);

 61     int tmp = c&s;

 62     s -= tmp;

 63     int t = tmp&(1<<(k*6));

 64     tmp -= t;

 65     tmp>>=1;

 66     tmp +=(t<<5);

 67     return s+tmp;

 68 }

 69 int inline row2(int k,int s)

 70 {

 71     c = 63<<(k*6);

 72     int tmp = c&s;

 73     s -= tmp;

 74     int t = tmp&(1<<(k*6+5));

 75     tmp -= t;

 76     tmp<<=1;

 77     tmp +=(t>>5);

 78     return s+tmp;

 79 }

 80 void bfs()

 81 {

 82     int head = 0,tail = 0;

 83     int cur = 0,tmp,i;

 84     for(i=7; i<=10; ++i)

 85         cur += 1<<i;

 86     for(i=13; i<=16; ++i)

 87         cur+= 1<<i;

 88     step[cur] = 1;

 89     q[tail++] = cur;

 90     

 91     while(head < tail)

 92     {

 93         cur = q[head++];

 94         for(i=0; i<6; ++i)

 95         {

 96             tmp = col1(i,cur);

 97             if(!step[tmp])

 98             {

 99             

100                 step[tmp] = step[cur] + 1;

101                 q[tail++] = tmp;

102             }

103             tmp = col2(i,cur);

104             if(!step[tmp])

105             {

106                 step[tmp] = step[cur] + 1;

107                 q[tail++] = tmp;

108             }

109         }

110         for(i=0; i<4; ++i)

111         {

112             tmp = row1(i,cur);

113             if(!step[tmp])

114             {

115                 step[tmp] = step[cur] + 1;

116                 q[tail++] = tmp;

117             }

118             tmp = row2(i,cur);

119             if(!step[tmp])

120             {

121                 

122                 step[tmp] = step[cur]+ 1;

123                 q[tail++] = tmp;

124             }

125         }

126     }

127 }

128 int main()

129 {

130     int t,k,i,j,w,g,b;

131     scanf("%d",&t);

132     char ch;

133     bfs();

134     for(k=1; k<=t; ++k)

135     {

136         w = g = b = 0;

137         for(i=0; i<4; ++i)

138         {

139             getchar();

140             for(j=0; j<6; ++j)

141             {

142                 scanf("%c",&ch);

143                 if(ch=='B')

144                     b += 1<<(i*6+j);

145                 else if(ch=='G')

146                     g += 1<<(i*6+j);

147                 else

148                     w += 1<<(i*6+j);

149             }

150         }    

151         printf("Case %d: %d\n",k,min(step[b]-1,min(step[g],step[w])-1));

152     }

153 }

 

你可能感兴趣的:(HDU)