UVA12510 Collecting Coins

来源:互联网 发布:淘宝怎么解封永久封号 编辑:程序博客网 时间:2024/05/26 09:54
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

33 4S.OC..O..XCX4 6S.X.CC..XOCC...O.C....XC4 4.SXCOO.C..XX.CCC 

Sample Output

16

3

该题真的有点烦,题目意思是推石头,捡金币,求最大的金币数目, 要求是要面向石头推 而且不能推出界,不能推到墙出,也不能推到金币处, 然后解法呢,借鉴了下,先第一次搜索,求得最小的金币数目,然后再一次次的推石头求所得金币数目,如果有增,则金币数加, 还得一次次的恢复原来的区域,求推石头之后得的最大金币数目。

代码如下;

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;char map[15][15];int biaoji[15][15];int shi[8][2],k;int n,m;int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}};int biao[8];int res,sum;void sou1(int x,int y,int ji)  //第一次全部遍历搜索  求最小的得金币数目 {    biaoji[x][y]=ji;    for (int i=0;i<4;i++){        int nx=x+dir[i][0];        int ny=y+dir[i][1];        if (nx<0 || nx>=n || ny<0 || ny>=m) continue;        if (biaoji[nx][ny]) continue;        if (map[nx][ny]=='O'|| map[nx][ny]=='X') continue;        if(map[nx][ny]=='C'){           res++;        }        sou1(nx,ny,ji);    }}void huifu(int x,int y,int ji)  //恢复 {    biaoji[x][y]=0;    for (int i=0;i<4;i++){        int nx=x+dir[i][0];        int ny=y+dir[i][1];        if (nx<0 || ny<0 || nx>=n || ny>=m) continue;        if (biaoji[nx][ny]!=ji) continue;        huifu(nx,ny,ji);    }}int maxn,ans;void shitou(int num){    char cc;    if (num>=k) return;    for (int i=0;i<k;i++){        if (biao[i]) continue;        biao[i]=1;        int x=shi[i][0];        int y=shi[i][1];        for (int j=0;j<4;j++){            int dx=x+dir[j][0];            int dy=y+dir[j][1];            if (dx<0 || dx>=n || dy<0 || dy>=m) continue;              if (map[dx][dy]=='X') continue;   //如果前面是X  就相当于朝向是旋转了90°,故不能推石头               if (!biaoji[dx][dy]) continue;   //如果没走过                                      int tx=x-dir[j][0];            int ty=y-dir[j][1];            if (tx<0 || tx>=n || ty<0 || ty>=m) continue;            if (map[tx][ty]!='.' && !biaoji[tx][ty]) continue;  //推的地方是金币             cc=map[tx][ty];            map[tx][ty]='O';            map[x][y]='.';            res=0;            sou1(x,y,i+2);  //更新标记的数字为i+2;  区别其他地方 好恢复             maxn+=res;            int tmp=res;            ans=max(ans,maxn);            shitou(num+1);                      huifu(x,y,i+2);  //恢复             maxn-=tmp;            map[tx][ty]=cc;            map[x][y]='O';        }        shitou(num+1);        biao[i]=0;    }}int main(){    int t,sx,sy;    scanf("%d",&t);    while (t--)    {        k=0;        scanf("%d%d",&n,&m);        for (int i=0;i<n;i++){            scanf("%s",map[i]);            for (int j=0;j<m;j++){                biaoji[i][j]=0;                if (map[i][j]=='S'){                    sx=i;sy=j;map[i][j]='.';                }                else                if (map[i][j]=='O')  //标记石头的位置 {                    shi[k][0]=i;                    shi[k++][1]=j;                }            }        }        res=0;        sou1(sx,sy,1);        sum=res;        maxn=0,ans=0;        memset(biao,0,sizeof(biao));        shitou(0);        ans+=sum;        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击