UVa 825 - Walking on the Safe Side(简单DP+数据读入)

Square City is a very easy place for people to walk around. The two-way streets run North-South or East-West dividing the city into regular blocks. Most street intersections are safe for pedestrians to cross. In some of them, however, crossing is not safe and pedestrians are forced to use the available underground passages. Such intersections are avoided by walkers. The entry to the city park is on the North-West corner of town, whereas the railway station is on the South-East corner.
Suppose you want to go from the park to the railway station, and do not want to walk more than the required number of blocks. You also want to make your way avoiding the underground passages, that would introduce extra delay. Your task is to determine the number of different paths that you can follow from the park to the station, satisfying both requirements.
The example in the picture illustrates a city with 4 E-W streets and 5 N-S streets. Three intersections are marked as unsafe. The path from the park to the station is 3 + 4 = 7 blocks long and there are 4 such paths that avoid the underground passages.
Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
The first line of the input contains the number of East-West streets W and the number of North- South streets N. Each one of the following W lines starts with the number of an East-West street, followed by zero or more numbers of the North-South crossings which are unsafe. Streets are numbered from 1.
Output
For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
The number of different minimal paths from the park to the station avoiding underground passages.
Sample Input
1
4 5
1
2 2
3 3 5
4
Sample Output

题目:在一个N*M的网格中,从左上角走到右下角,有一些点不能经过,求最短路的条数。

分析:如果简单的来看,那这就是一个简单的DP。状态f[i][j] 表示走到(i,j)的方案数,只用考虑向左走和向下走的情况。

题目坑点:
虽然这样写感觉题目很水,能AC,但其实仔细思考感觉还有很多情况没有考虑出来,或者说题目表达完备。
一开始想得比较多,,,比如可能由于陷阱的原因,不得不向右走再向左走然后才能到达终点,,因为题目并规定行走的方向,只是说了能到达的最短路。这样的话,用上面的方式转移就出不了正确结果。但事实证明没有出这样的数据来卡。。。。
并且题目没有说数据范围。。。太不规范了。

收获:
所以这道题的主要收获还是get了一种新的读入方式。。。
stringstream 这样处理字符串,可以直接提取字符串中由空格隔开的数字。

#include <sstream>
string s;
int main()
{
    getline(cin,s);
    stringstream ss(s);
    while(ss>>num) a[num]=1; //将这个字符串里由空格分开的数字串 作为数字取出来
}

题目源码:

// Created by ZYD in 2015.
// Copyright (c) 2015 ZYD. All rights reserved.
//

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define Size 100000
#define ll long long
#define mk make_pair
#define pb push_back
#define mem(array) memset(array,0,sizeof(array))
typedef pair<int,int> P;
string s;
int dp[1005][1005],used[1005][1005],n,m,t;
int main()
{
    freopen("in.txt","r",stdin);
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        mem(used);
        mem(dp);
        for(int i=1;i<=n;i++)
        {
            int x,lie;
            scanf("%d",&x);
            getline(cin,s);
            stringstream ss(s);
            while(ss>>lie) used[x][lie]=1;
        }
        dp[0][1]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            if(!used[i][j])
            {
                dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        cout<<dp[n][m]<<endl;   
        if(t) cout<<endl;
    }
    return 0;
}


你可能感兴趣的:(dp,uva)