Robots on a grid | ||||||
|
||||||
Description | ||||||
You have recently made a grid traversing robot that can find its way from the top left corner of a grid to the bottom right corner. However, you had forgotten all your AI programming skills, so you only programmed your robot to go rightwards and downwards (that's after all where the goal is). You have placed your robot on a grid with some So you decide to write a program that, given a grid of size n x n with some obstacles marked on it where the robot cannot walk, counts the different ways the robot could go from the top left corner s to the bottom right t, and if none,tests if it were possible if it could walk up and left as well.However, your program does not handle very large numbers, so the answer should be given modulo 2^31-1. |
||||||
Input | ||||||
There are several test cases. For each test case: On the first line is one integer, 1<=n<=1000. Then follows n lines, each with n characters,where each character is one of'.'and'#', where ' . ' is to be interpreted as a walkable tile and'#'as a non-walkable tile. There will never be a wall at s, and there will never be a wall at t. |
||||||
Output | ||||||
For each test case: Output one line with the number of different paths starting in s and ending in t(modulo 2^31- 1) orTHE GAME IS A LIE if you cannot go from s to t going only rightwards and downwards but you can if you are allowed to go left and up as well, or INCONCEIVABLE if there simply is no path from s to t. |
||||||
Sample Input | ||||||
5 ......# ####... .#..... .#...#. .#..... .#..### .#.....
|
||||||
Sample Output | ||||||
6 THE GAME IS A LIE
|
||||||
Source | ||||||
NCPC2011 |
题目大意:起点(0,0)终点(n-1,n-1)如果不能通过走四个方向走到终点,输出INCONCEIVABLE。否则继续判断,如果不能够通过只向右向下两种方法输出THE GAME IS A LIE,否则输出所有路径数,能够从0,0到n-1,n-1的个数。
思路:BFS+BFS+dp、
第一遍bfs判断能否能够通过四个方向走到终点,第二遍BFS判断能否通过两个方向走到终点。一开始决定用两次BFS+一次DFS回溯累加路径数的,可惜因为n比较大,TLE了,没办法另寻他路,突然想起以前在理工做过这样一个题:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2003,用dp的方法就能得到从(0,0)到(n-1,n-1)的总路径数,首先设dp【i】【j】表示走到点(i,j)的总路径数,那么不难推出状态转移方程:
dp【i】【j】=dp【i-1】【j】+dp【i】【j-1】;表示走到点i,j的总方法数来自从左边过来的和从上边过来的路径数之和。
思路已经构建完毕,辣么我们需要做的就是写啊写啊写代码啦~
注意的点:别忘记取模
#include<stdio.h> #include<string.h> #include<queue> using namespace std; #define mod 2147483647 struct zuobiao { int x,y; }now,nex; int ans; long long dp[1005][1005]; char a[1005][1005]; int vis[1005][1005]; int output[1005][1005]; int fx[4]={0,1,-1,0}; int fy[4]={1,0,0,-1}; int fx2[2]={0,-1}; int fy2[2]={-1,0}; int n; void bfs(int x,int y) { memset(output,0,sizeof(output)); memset(vis,0,sizeof(vis)); queue<zuobiao >s; now.x=x; now.y=y; vis[now.x][now.y]=1; output[now.x][now.y]=1; s.push(now); while(!s.empty()) { now=s.front(); s.pop(); for(int i=0;i<2;i++) { nex.x=now.x+fx[i]; nex.y=now.y+fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<n&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#') { vis[nex.x][nex.y]=1; output[nex.x][nex.y]=output[now.x][now.y]+1; s.push(nex); } } } } int bfs0(int x,int y) { memset(vis,0,sizeof(vis)); queue<zuobiao >s; now.x=x; now.y=y; vis[now.x][now.y]=1; s.push(now); while(!s.empty()) { now=s.front(); if(now.x==n-1&&now.y==n-1) { return 1; } s.pop(); for(int i=0;i<4;i++) { nex.x=now.x+fx[i]; nex.y=now.y+fy[i]; if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<n&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#') { vis[nex.x][nex.y]=1; output[nex.x][nex.y]=output[now.x][now.y]+1; s.push(nex); } } } return 0; } int main() { while(~scanf("%d",&n)) { for(int i=0;i<n;i++)scanf("%s",a[i]); int aaa=bfs0(0,0); if(aaa==0){printf("INCONCEIVABLE\n");continue;} bfs(0,0); if(output[n-1][n-1]==0) { printf("THE GAME IS A LIE\n"); } else { memset(dp,0,sizeof(dp)); dp[1][1]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==1&&j==1)continue; if(output[i-1][j-1]) { dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mod; } else dp[i][j]=0; } } printf("%lld\n",dp[n][n]%mod); } } }