HDU 2977 Color Squares BFS
題目描述:
Problem Description
You have a 3 * 3 board of color squares. Each square is either empty or has a block in it. Initially, all the squares are empty. There are four kinds of blocks: blue (B), red (R), green (G) and yellow (Y). Each of these block scores wb, wr, wg and wy , respectively (blocks of the same color always have the same score). We assume that wb<=wr<=wg<=wy .
In each step, you can place a new block in a square. If that square already has a block in it, take it out first (taking it out does not count as a step). You can do this as many times as you like (you’re given enough blocks for each color), as long as you follow these rules:
Rule 1: You can always place a blue block.
Rule 2: You can place a red block if and only if it’s surrounded by at least one blue block.
Rule 3: You can place a green block if and only if it’s surrounded by at least one blue and one red block.
Rule 4: You can place a yellow block if and only if it’s surrounded by at least one blue, one red and one green block
Every square is surrounded by squares that share one edge with it, so each of four corner squares is surrounded by exactly two squares, each of four squares on the edge (but not at corners) is surrounded by exactly three squares, and the center square is surrounded by exactly four squares.
Write a program to find the minimal number of steps needed to get a score of at least w . The total score is the sum of individual scores of each block on the current board, regardless of what blocks you’ve thrown away.
Input
The input contains several test cases. Each case contains five positive integer, wb, wr, wg, wy, w (1<=wb<=wr<=wg<=wy≤100, 0<=w<=1000) in a single line. The last test case is followed by a single zero, which should not be processed.
Output
For each test case, print the case number and the minimum number of steps. If it is impossible, output “Impossible”.
Sample Input
1 1 1 1 3 1 2 4 8 21 1 1 1 100 500 7 20 53 94 395 0Sample Output
Case 1: 3 Case 2: 7 Case 3: Impossible Case 4: 11Source
2007 Asia Regional Beijing
題目分析:
一個3*3的正方形方格中,可以填入B R G Y 四種顏色。(初始網格無色)
其中,B色填涂無需別的約束條件;
R色填涂需要其方格上下左右四個方向中至少有一個方格顏色為B;
G色填涂需要其方格上下左右四個方向中至少有一個方格顏色為B,至少有一個方格顏色為R;
Y色填涂需要其方格上下左右四個方向中分別至少有一個B,一個R,一個G。
方格在每種不同的顏色都有其特殊的分數,其中保證Vy>=Vg>=Vr>=Vb。
你的最終得分為每個方格中的得分之和。
你可以將一個已經填了顏色的方格重新填色,新的顏色會覆蓋原顏色。
給一個w,求你在最少的步數能夠達到或大于這個分數。
其實BFS的搜索思路還是很清晰的,就是問題是如何存儲復雜的狀態,由于這個網格是3*3的,也就是說只有9個方格,所以我們可以用9維數組來存儲狀態是否被訪問(每一維記錄這個方格的狀態),用4維數組記錄到達這四種顏色狀態的最短步數(因為權和之和方格上的顏色和其個數決定,和其位置無關),然后就是BFS搜索填涂四種顏色的情況。
其實這道題如果網格更大,就不能用數組存儲狀態了,因為會MLE(而且寫起來也要爆炸),就是一道BFS+狀壓的題,然而這題每個方格狀態有5個,也就是壓縮成5進制了。(和普通的二進制狀壓不同了)
不過這些都是后話。
這題的算法就是這樣。
代碼如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> #include <queue>const int INF=0x3f3f3f3f; using namespace std;int vis[5][5][5][5][5][5][5][5][5]; int dir[4][2]= {-1,0,1,0,0,-1,0,1}; int steps[10][10][10][10]; struct sa {int mp[3][3];int step;int num[5]; };int b,r,g,y,w; int cas;void init() {memset(vis,0,sizeof(vis));memset(steps,INF,sizeof(steps)); }void BFS() {queue<sa>q;sa u;u.step=0;memset(u.mp,0,sizeof(u.mp));memset(u.num,0,sizeof(u.num));q.push(u);vis[0][0][0][0][0][0][0][0][0]=1;while(!q.empty()){sa u=q.front();q.pop();steps[u.num[1]][u.num[2]][u.num[3]][u.num[4]]=min(u.step,steps[u.num[1]][u.num[2]][u.num[3]][u.num[4]]);for(int i=0; i<3; i++)for(int j=0; j<3; j++){int num1=0,num2=0,num3=0;int pre=u.mp[i][j];//print Bif (u.mp[i][j]!=1){u.step++;u.num[1]++;u.num[pre]--;u.mp[i][j]=1;if (!vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]){vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]=1;q.push(u);}u.mp[i][j]=pre;u.num[pre]++;u.num[1]--;u.step--;}//print Rfor(int k=0; k<4; k++){int nx=i+dir[k][0];int ny=j+dir[k][1];if (nx>=0 && ny>=0 && nx<3 && ny<3){if (u.mp[nx][ny]==1) num1++;}}if (num1 && u.mp[i][j]!=2){u.step++;u.num[2]++;u.num[pre]--;u.mp[i][j]=2;if (!vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]){vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]=1;q.push(u);}u.mp[i][j]=pre;u.num[pre]++;u.num[2]--;u.step--;}//print Gnum1=0,num2=0,num3=0;for(int k=0; k<4; k++){int nx=i+dir[k][0];int ny=j+dir[k][1];if (nx>=0 && ny>=0 && nx<3 && ny<3){if (u.mp[nx][ny]==1) num1++;if (u.mp[nx][ny]==2) num2++;}}if (num1 && num2 && u.mp[i][j]!=3){u.step++;u.num[3]++;u.num[pre]--;u.mp[i][j]=3;if (!vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]){vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]=1;q.push(u);}u.mp[i][j]=pre;u.num[pre]++;u.num[3]--;u.step--;}//print Ynum1=0,num2=0,num3=0;for(int k=0; k<4; k++){int nx=i+dir[k][0];int ny=j+dir[k][1];if (nx>=0 && ny>=0 && nx<3 && ny<3){if (u.mp[nx][ny]==1) num1++;if (u.mp[nx][ny]==2) num2++;if (u.mp[nx][ny]==3) num3++;}}if (num1 && num2 && num3 && u.mp[i][j]!=4){u.step++;u.num[4]++;u.num[pre]--;u.mp[i][j]=4;if (!vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]){vis[u.mp[0][0]][u.mp[0][1]][u.mp[0][2]][u.mp[1][0]][u.mp[1][1]][u.mp[1][2]][u.mp[2][0]][u.mp[2][1]][u.mp[2][2]]=1;q.push(u);}u.mp[i][j]=pre;u.num[pre]++;u.num[4]--;u.step--;}}} }int main() {cas=0;init();BFS();while(scanf("%d",&b)!=-1 && (b!=0)){scanf("%d%d%d%d",&r,&g,&y,&w);printf("Case %d: ",++cas);int ans=INF;for(int i=0; i<=9; i++)for(int j=0; j<=9; j++)for(int k=0; k<=9; k++)for(int l=0; l<=9; l++)if (i*b+j*r+k*g+l*y>=w)ans=min(ans,steps[i][j][k][l]);if (ans==INF) printf("Impossible\n");else printf("%d\n", ans);}return 0; }總結
以上是生活随笔為你收集整理的HDU 2977 Color Squares BFS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity常用事件函数与变量
- 下一篇: 【TCO2013 Semifinal 2