POJ1027-The Same Game
转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1308971668
大致题意:
在一个固定大小为10x15的矩形区域A内被RGB三种颜色的小球填满
现在按如下步骤操作:
1、 删除区域A内最大的一片区域M(任意颜色都可以,只要其占有区域最大)
2、 删除M后,自然会出现空的位置,在M区域上方的小球自然下落;
当删除M后出现空列时,右边的列往左填充。
注意是以“列”为单位填充,非空列只能整列往空列移动。
移动后,各个小球之间的相对顺序 与 移动前一样。
3、 当区域A剩余小球数为0,或A内的最大区域为1时,游戏结束。否则返回1。
输出每一步的得分,最后输出总得分。
解题思路:
没难度的模拟题,直接模拟就可以了,1次AC。
关键在于删除矩形区域M后的刷新地图操作。
寻找最大区域M,和删除M区域都是用BFS执行。
题目要求: 区域Z的坐标 = 在区域Z左下角的小球的坐标
因此为了对应坐标,
输入map时,行从9~0输入,列从0~14输入
搜索最大区域时,列从0~14优先搜索,行再从0~9搜索
输出坐标时记得行列+1
1 //Memory Time
2 //264K 407MS
3
4 #include<iostream>
5 using namespace std;
6
7 char map[10][16];
8 bool vist[10][15];
9 int MaxSize=-1;
10 char MaxColor;
11 int MaxR,MaxC;
12
13 void SearchMaxArea(void); //搜索当前地图的最大区域
14 int BFSArea(int i,int j); //同色区域搜索,返回该区域的大小
15 void DelMaxArea(void); //删除最大区域
16 void RefreshMap(void); //刷新地图
17
18 int main(void)
19 {
20 int Game;
21 cin>>Game;
22 for(int g=1;g<=Game;g++)
23 {
24 for(int k=9;k>=0;k--)
25 cin>>map[k];
26 cout<<"Game "<<g<<':'<<endl<<endl;
27
28 int step=0;
29 int RemainBalls=150;
30 int SumScore=0;
31 while(true)
32 {
33 MaxSize=-1;
34 SearchMaxArea();
35
36 if(MaxSize==0 || MaxSize==1)
37 break;
38
39 DelMaxArea();
40 RefreshMap();
41
42 int score=(MaxSize-2)*(MaxSize-2);
43 cout<<"Move "<<++step<<" at ("<<MaxR+1<<','<<MaxC+1<<"): ";
44 cout<<"removed "<<MaxSize<<" balls of color "<<MaxColor<<", got "<<score<<" points."<<endl;
45
46 RemainBalls-=MaxSize;
47 SumScore+=score;
48 }
49 if(RemainBalls==0)
50 SumScore+=1000;
51 cout<<"Final score: "<<SumScore<<", with "<<RemainBalls<<" balls remaining."<<endl<<endl;
52 }
53 return 0;
54 }
55
56 /*搜索当前地图的最大区域*/
57 void SearchMaxArea(void)
58 {
59 memset(vist,false,sizeof(vist));
60 MaxSize=0;
61
62 for(int j=0;j<15;j++) //从左下角开始搜索
63 for(int i=0;i<10;i++)
64 {
65 int size=0;
66 if(!vist[i][j] && map[i][j])
67 {
68 size=BFSArea(i,j);
69 if(MaxSize<size) //记录最大区域的左下角坐标
70 {
71 MaxSize=size;
72 MaxR=i;
73 MaxC=j;
74 }
75 }
76 }
77 return;
78 }
79
80 /*同色区域搜索*/
81 int BFSArea(int i,int j)
82 {
83 class
84 {
85 public:
86 int x,y;
87 }queue[151];
88
89 int head,tail;
90 queue[head=tail=0].x=i;
91 queue[tail++].y=j;
92 vist[i][j]=true;
93
94 int size=0;
95 char color=map[i][j];
96 while(head<tail)
97 {
98 int x=queue[head].x;
99 int y=queue[head++].y;
100 size++;
101
102 if(x+1<10 && !vist[x+1][y] && map[x+1][y]==color) //上
103 {
104 vist[x+1][y]=true;
105 queue[tail].x=x+1;
106 queue[tail++].y=y;
107 }
108 if(x-1>=0 && !vist[x-1][y] && map[x-1][y]==color) //下
109 {
110 vist[x-1][y]=true;
111 queue[tail].x=x-1;
112 queue[tail++].y=y;
113 }
114 if(y-1>=0 && !vist[x][y-1] && map[x][y-1]==color) //左
115 {
116 vist[x][y-1]=true;
117 queue[tail].x=x;
118 queue[tail++].y=y-1;
119 }
120 if(y+1<15 && !vist[x][y+1] && map[x][y+1]==color) //右
121 {
122 vist[x][y+1]=true;
123 queue[tail].x=x;
124 queue[tail++].y=y+1;
125 }
126 }
127 return size;
128 }
129
130 /*删除最大区域*/
131 void DelMaxArea(void)
132 {
133 class
134 {
135 public:
136 int x,y;
137 }queue[151];
138
139 int head,tail;
140 queue[head=tail=0].x=MaxR;
141 queue[tail++].y=MaxC;
142
143 MaxColor=map[MaxR][MaxC];
144 map[MaxR][MaxC]=0; //删除该格上的球
145
146 while(head<tail)
147 {
148 int x=queue[head].x;
149 int y=queue[head++].y;
150 map[x][y]=0;
151
152 if(x+1<10 && map[x+1][y]==MaxColor) //上
153 {
154 map[x+1][y]=0;
155 queue[tail].x=x+1;
156 queue[tail++].y=y;
157 }
158 if(x-1>=0 && map[x-1][y]==MaxColor) //下
159 {
160 map[x-1][y]=0;
161 queue[tail].x=x-1;
162 queue[tail++].y=y;
163 }
164 if(y-1>=0 && map[x][y-1]==MaxColor) //左
165 {
166 map[x][y-1]=0;
167 queue[tail].x=x;
168 queue[tail++].y=y-1;
169 }
170 if(y+1<15 && map[x][y+1]==MaxColor) //右
171 {
172 map[x][y+1]=0;
173 queue[tail].x=x;
174 queue[tail++].y=y+1;
175 }
176 }
177 return;
178 }
179
180 /*刷新地图*/
181 void RefreshMap(void)
182 {
183 bool empty[15]={false};
184 int i,j;
185
186 /*处理从上到下的移动*/
187 for(j=0;j<15;j++)
188 {
189 bool flag=false; //标记第j列是否全列为空
190 int pi=-1;
191 for(i=0;i<10;i++)
192 {
193 if(map[i][j])
194 {
195 flag=true;
196 if(pi!=-1)
197 {
198 map[pi][j]=map[i][j];
199 map[i][j]=0;
200 i=pi;
201 pi=-1;
202 }
203 }
204 else
205 {
206 pi=i;
207 while(i+1<10 && !map[i+1][j])
208 i++;
209 }
210 }
211 if(!flag)
212 empty[j]=true; //第j列为空
213 }
214
215 /*处理从右到左的移动*/
216 int k=-1;
217 for(j=0;j<15;j++)
218 {
219 if(!empty[j])
220 {
221 if(k!=-1)
222 {
223 for(int x=0;x<10;x++)
224 {
225 map[x][k]=map[x][j];
226 map[x][j]=0;
227 }
228 empty[j]=true;
229 j=k;
230 k=-1;
231 }
232 }
233 else
234 {
235 k=j;
236 while(j+1<15 && empty[j+1])
237 j++;
238 }
239 }
240
241 return;
242 }
[ EXP技术分享博客 ] 版权所有,转载请注明出处: http://exp-blog.com