<Google>Problem D. Dragon Maze

来源:互联网 发布:seo quake 编辑:程序博客网 时间:2024/05/18 03:41

谷歌是彻底跪了,今天的第二轮在线编程就做出一道半,这题做出了小数据量的,大数据量的由于8分钟限时的原因,没能提交,晚上继续剪枝终于成功。

最开始的直观想法就是模拟栈,四个方向判断入栈,这种暴力的方法勉强能过小数据(某些case也花了一些时间),在大数据8分钟计时开始后突然才想到这是一个贪心算法,赶紧改代码,增加了一个二维矩阵记录从起点出发到各点的最短距离,当时时间有限,结果没跑对。晚上回来继续将其完成,测小数据秒过,但是大数据还是卡住了,想到可能还需要进一步剪枝,减少不必要的入栈,于是再用一个二维数组记录各点的最大能量,用于处理各点最短距离和当前距离相等时,利用能量值将大部分本会入栈的结点排除掉。最后测了下,感觉时间比较满意了。。。


Problem

You are the prince of Dragon Kingdom and your kingdom is in danger of running out of power. You must find power to save your kingdom and its people. An old legend states that power comes from a place known as Dragon Maze. Dragon Maze appears randomly out of nowhere without notice and suddenly disappears without warning. You know where Dragon Maze is now, so it is important you retrieve some power before it disappears.

Dragon Maze is a rectangular maze, an N x M grid of cells. The top left corner cell of the maze is (0,0) and the bottom right corner is (N-1, M-1). Each cell making up the maze can be either a dangerous place which you never escape after entering, or a safe place that contains a certain amount of power. The power in a safe cell is automatically gathered once you enter that cell, and can only be gathered once. Starting from a cell, you can walk up/down/left/right to adjacent cells with a single step.

Now you know where the entrance and exit cells are, that they are different, and that they are both safe cells. In order to get out of Dragon Maze before it disappears, you must walk from the entrance cell to the exit cell taking as few steps as possible. If there are multiple choices for the path you could take, you must choose the one on which you collect as much power as possible in order to save your kingdom.

Input

The first line of the input gives the number of test cases, TT test cases follow.

Each test case starts with a line containing two integers N and M, which give the size of Dragon Maze as described above. The second line of each test case contains four integers enxenyexxexy, describing the position of entrance cell (enx, eny) and exit cell (exx, exy). Then N lines follow and each line has M numbers, separated by spaces, describing the N x M cells of Dragon Maze from top to bottom. Each number for a cell is either -1, which indicates a cell is dangerous, or a positive integer, which indicates a safe cell containing a certain amount of power.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1). If it's possible for you to walk from the entrance to the exit, y should be the maximum total amount of power you can collect by taking the fewest steps possible. If you cannot walk from the entrance to the exit, y should be the string "Mission Impossible." (quotes for clarity). Please note that the judge requires an exact match, so any other output like "mission impossible." or "Mission Impossible" (which is missing the trailing period) will be judged incorrect.

Limits

The amount of power contained in each cell will not exceed 10,000.
1 ≤ T ≤ 30.
0 ≤ enxexx < N.
0 ≤ enyexy < M.

Small dataset

1 ≤ NM ≤ 10.

Large dataset

1 ≤ NM ≤ 100.

Sample


Input 
 
Output 
 
22 30 2 1 02 -1 53 -1 64 40 2 3 2-1 1 1 21 1 1 12 -1 -1 11 1 1 1
Case #1: Mission Impossible.Case #2: 7


#include<iostream>#include<memory>using namespace std;int matrix[101][101];int m,n;bool v[101][101];int pointMin[101][101];int pointMin1[101][101];bool can(int x,int y,int head,int&xx,int&yy){switch(head){case 0:if(x>0&&matrix[x-1][y]!=-1&&v[x-1][y]==false){xx = x-1;yy=y;return true;}return false;break;case 1:if(y<n-1&&matrix[x][y+1]!=-1&&v[x][y+1]==false){xx=x;yy=y+1;return true;}return false;break;case 2:if(x<m-1&&matrix[x+1][y]!=-1&&v[x+1][y]==false){xx=x+1;yy=y;return true;}return false;break;case 3:if(y>0&&matrix[x][y-1]!=-1&&v[x][y-1]==false){xx=x;yy=y-1;return true;}return false;break;default:return false;}}int maxNum;int minlen;bool fun(int sx,int sy,int ex,int ey){int stkx[10000],stky[10000],acc[10000],head[10000],top=0;int tx,ty;bool ret = false;int px,py,pacc,phead,mintmp;memset(v,0,sizeof(v));memset(pointMin, 0, sizeof(pointMin));if(matrix[sx][sy]==-1||matrix[ex][ey]==-1)return false;if(!can(ex,ey,0,tx,ty)&&!can(ex,ey,1,tx,ty)&&!can(ex,ey,2,tx,ty)&&!can(ex,ey,3,tx,ty))return false;if(sx==ex&&sy==ey){maxNum = matrix[sx][sy];return true;}stkx[0] = sx;stky[0] = sy;acc[0] = matrix[sx][sy];head[0] = 0;top=1;while(top>0){px = stkx[top-1];py = stky[top-1];pacc = acc[top-1];phead = head[top-1];if(px==ex&&py==ey){ret = true;if(top<minlen){minlen = top;maxNum = pacc;}else if(top==minlen&&pacc>maxNum){maxNum = pacc;}v[px][py] = false;--top;continue;}if(phead>3){v[px][py] = false;--top;continue;}if(can(px,py,phead,tx,ty)&& top+1<=minlen &&( pointMin[tx][ty]==0||(pointMin[tx][ty]>top)|| (pointMin[tx][ty]==top&&pointMin1[tx][ty]<acc[top-1] + matrix[tx][ty]) )){v[tx][ty] = true;head[top-1]++;pointMin[tx][ty] = top;pointMin1[tx][ty]= acc[top-1] + matrix[tx][ty];stkx[top] = tx;stky[top] = ty; acc[top] = acc[top-1] + matrix[tx][ty];head[top] = 0;++top;continue;}elsehead[top-1]++;}return ret;}FILE *fin,*fout;int main(){int T,c,i,j,x,y;int sx,sy,ex,ey;fout = fopen("out1.txt","w");fin = fopen("in1.txt","r");fscanf(fin,"%d",&T);for(c=1;c<=T;c++){fscanf(fin,"%d%d",&m,&n);fscanf(fin,"%d%d%d%d",&sx,&sy,&ex,&ey);for(i=0;i<m;i++)for(j=0;j<n;j++)fscanf(fin,"%d",&matrix[i][j]);maxNum = 0;minlen = 1000000;if(fun(sx,sy,ex,ey))fprintf(fout,"Case #%d: %d\n",c,maxNum);elsefprintf(fout,"Case #%d: Mission Impossible.\n",c);printf("Case #%d\n",c);}fclose(fout);return 0;}