【u105】路径计数2

来源:互联网 发布:php去除字符串的空格 编辑:程序博客网 时间:2024/05/29 11:17

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

一个N×N的网格,你一开始在(1, 1),即左上角。每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N, N),即右下角有多少种方法。 但是这个问题太简单了,所以现在有M个格子上有障碍,即不能走到这M个格子上。


【输入格式】

输入文件path.in的第1行包含两个非负整数N,M,表示了网格的边长与障碍数。 接下来M行,每行两个不大于N的正整数x, y。表示坐标(x, y)上有障碍不能通过,且有1≤x, y≤n,且x, y至少有一个大于1,并请注意障碍坐标有可能相同。

【输出格式】

输出文件path.out仅包含一个非负整数,为答案mod 100003后的结果。

【数据规模】

对于20%的数据,有N≤3; 对于40%的数据,有N≤100; 对于40%的数据,有M=0; 对于100%的数据,有N≤1000,M≤100000。

Sample Input1

3 13 1

Sample Output1

5

【题解】

这题和马拦过河卒那题很像。

但是这题更好做了。不用你处理出马控制的区域。直接告诉你哪些格子不能走了。

一开始和(1,1)在同一行和同一列的位置都置为1;遇到不能走的则停止置。

然后用递推公式

a[i][j] = (a[i-1][j]+a[i][j-1] )%100003递推即可。

【代码】

#include <cstdio>#include <cstring>int n,m,a[1001][1001] = {0};bool bo[1001][1001];void input_data(){memset(bo,true,sizeof(bo));//一开始置所有的点都可以走 scanf("%d%d",&n,&m);for (int i = 1;i <= m;i++) //输入m个不能走的点 并将其bo值置为false; {int x,y;scanf("%d%d",&x,&y);bo[x][y] = false;}for (int i = 1;i <= n;i++) //和(1,1)在同一行或同一列都只有一种到达方式。如果有不能走到的点 if (bo[1][i])//在这一行或一列上。它后面被挡住的点就无法到达了。 a[1][i] = 1;elsebreak;for (int i = 1;i <= n;i++)  if (bo[i][1])a[i][1] = 1;elsebreak;}void get_ans() //根据过河卒的思路来递推答案即可。 {for (int i = 2;i <= n;i++)for (int j = 2;j <= n;j++)if (bo[i][j])a[i][j] = (a[i-1][j]+a[i][j-1]) % 100003; //要记住取模运算! }void output_ans(){printf("%d\n",a[n][n]);}int main(){input_data();get_ans();output_ans();return 0;}


0 0