1. 程式人生 > >Somebody I can kiss CSU

Somebody I can kiss CSU

In a maze of r rows and c columns, your task is to collect as many coins as possible.
Each square is either your start point “S”(which will become empty after you leave), an empty square “.”, a coin square “C” (which will become empty after you step on this square and thus collecting the coin), a rock square “O” or an obstacle square “X”.
At each step, you can move one square to the up, down, left or right. You cannot leave the maze or enter an obstacle square, but you can push each rock at most once (i.e. You can treat a rock as an obstacle square after you push it).
To push a rock, you must stand next to it. You can only push the rock along the direction you’re facing, into an neighboring empty square (you can’t push it outside the maze, and you can’t push it to a squarecontiaining a coin).For example, if the rock is to your immediate right, you can only push it to its right neighboring square.
Find the maximal number of coins you can collect.
Input
The first line of input contains a single integer T (T<=25), the number of test cases.
Each test case begins with two integers r and c (2<=r,c<=10), then followed by r lines, each with c columns.
There will be at most 5 rocks and at most 10 coins in each maze.
Output
For each test case, print the maximal number of coins you can collect.

Sample Input
3
3 4
S.OC
..O.
.XCX
4 6
S.X.CC
..XOCC
…O.C
….XC
4 4
.SXC
OO.C
..XX
.CCC
Sample Output
1
6
3
題意:有一個n*m的矩陣,S是人開始的位置,O是石頭,C是金幣,X是牆。石頭最多隻能推一次,現在問你最多能拿到多少個金幣
思路:我們不能直接用人去做BFS一條路走到死。肯定會TLE,因為在碰到石頭之前的狀態其實都是一樣的,而你用BFS會多出很多很多狀態。
所以我們先用BFS跑出石頭沒動時人能走到的所有的位置,並且把吃到的金幣數記下來,對應的圖從C改成.
然後用DFS去列舉石頭移動的所有情況(向四個方向移動),最後在所有情況裡面取吃到的金幣數最大的那個就可以了。注意要開三維陣列儲存上一層的圖和標記陣列。

#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
#define pi 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899
char mapp[6][15][15]; int v[6][15][15]; int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; int n,m,cnt; int x2,y2; int go(int x,int y,int k) { if(0<=x&&x<n&&0<=y&&y<m&&mapp[k][x][y]!='X'&&mapp[k][x][y]!='O') return 1; return 0; } struct node { int x,y; } stone[6]; int ma,last_ma,num,flag[6]; void bfs(node a,int k) { node st,ed; queue<node>q; q.push(a); v[k][a.x][a.y]=1; while(!q.empty()) { st=q.front(); q.pop(); for(int i=0; i<4; i++) { ed.x=st.x+dir[i][0]; ed.y=st.y+dir[i][1]; if(!go(ed.x,ed.y,k)||v[k][ed.x][ed.y]) continue; if(mapp[k][ed.x][ed.y]=='C') { ma++; last_ma=max(last_ma,ma); mapp[k][ed.x][ed.y]='.'; } v[k][ed.x][ed.y]=1; q.push(ed); } } } void dfs(int k) { for(int i=0; i<cnt; i++) { if(flag[i]) continue; for(int j=0; j<4; j++) { int tx=stone[i].x+dir[j][0]; int ty=stone[i].y+dir[j][1]; if(tx<0||tx>=n||ty<0||ty>=m||mapp[k-1][tx][ty]!='.') continue; int ttx=stone[i].x-dir[j][0]; int tty=stone[i].y-dir[j][1]; if(ttx<0||ttx>=n||tty<0||tty>=m||!v[k-1][ttx][tty]) continue; memcpy(v[k],v[k-1],sizeof(v[k])); memcpy(mapp[k],mapp[k-1],sizeof(mapp[k])); mapp[k][tx][ty]='X',mapp[k][stone[i].x][stone[i].y]='.'; flag[i]=1; bfs(stone[i],k); if(last_ma==num) return; dfs(k+1); if(last_ma==num) return; for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(mapp[k-1][i][j]=='C'&&mapp[k][i][j]=='.') ma--; flag[i]=0; } } } int main() { int t; node a; scanf("%d",&t); while(t--) { ma=last_ma=num=0; cnt=0; scanf("%d%d",&n,&m); for(int i=0; i<n; i++) { scanf("%s",mapp[0][i]); for(int j=0; j<m; j++) { if(mapp[0][i][j]=='S') { a.x=i,a.y=j; mapp[0][i][j]='.'; } else if(mapp[0][i][j]=='O') stone[cnt].x=i,stone[cnt++].y=j; else if(mapp[0][i][j]=='C') num++; } } memset(v[0],0,sizeof(v[0])); memset(flag,0,sizeof(flag)); bfs(a,0); dfs(1); printf("%d\n",last_ma); } }