SOJ 1033

来源:互联网 发布:建筑技术变革 知乎 编辑:程序博客网 时间:2024/06/05 16:42

1033. City Road

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Long long ago, city Old was all around the water and was divided into M*N small square houses. The city Old had only two bridges, in the southwest corner and northeast corner. It’s obvious that the citizens can have C(m+n, n) different ways with shortest length, to go from one bridge to the other.

     As the city developed, bigger buildings came out and blocked some streets. These new buildings were always large rectangles combining many small houses. Since the new buildings may affect the number of shortest ways a lot, it’s you job now to recalculate the number.

     The city has M rows and N columns of houses, M+1 horizontal streets, and N+1 vertical streets. Suppose the house in the southwest corner is (1, 1), then the house in the northeast corner can be marked as (m, n). And then each new building can be described by its southwest corner(house) and its size(number of houses) in horizontal and vertical directions.

     The picture below shows that the city Old has 5*6 houses and one 3*2 building with its southwest corner located at (2,4). The number of different shortest ways in the picture is 192.

Input

This problem has multiple test cases. In each test case, the first line is two integer m, n(m*n<=1,000,000)which indicate the size of city Old, in vertical and horizontal directions respectively. And the second line has one integer B(B<=1000) what is the number of the new buildings. After that there are B lines. Each line has four integers x, y, a, b, describing the southwest corner (x, y) , the vertical size a, and the horizontal size b of the building. The buildings may be overlapped with each other. The input is terminated by a case with m*n=0, which should not be processed.

Output

For each test case output one integer representing the number of shortest ways in a single line. This number is guaranteed to be less than 2^63.

Sample Input

5 612 4 3 20 0

Sample Output

192

Problem Source

ZSUACM Team Member


  动态规划的思路,由于求得是最短路径的数量,所以到达右上角点的最后一步只能是向上到达右上角或者向右到达右上角,设dp[i,j]为到达(i,j)最短路径的数量,则状态转移方程为dp[m,n]=dp[m-1,n]+dp[m,n-1],先确定第一行第一列的边界值,然后依此递推即可。

  这题明显用二维数组会更方便一些,但我动态申请二维数组结果是内存超了,换成用静态的一维数组来存储才可以AC,也不知道是为什么。


// Problem#: 1033// Submission#: 5054060// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include<iostream>#include<cstring>using namespace std;struct node{//used用来判断是否这一点被建筑阻挡无法到达,value用来保存从左下角到这一点最短路径的数量     int used;    long long value;     node()    {        used=0;        value=0;    }};node city[2000003];//用来存放节点,将二维形式的数据存放在一维数组里,即(i,j)存放在(i-1)*n+j里 int m,n,B;//m为行数,n为列数,B为阻碍物数量 void readData(){    for(int i=1;i<=m*n;++i)//先全部设为0     {        city[i].used=0;        city[i].value=0;    }    for(int i=0;i<B;++i)    {        int x,y,a,b;        cin>>x>>y>>a>>b;        for(int j=x+1;j<x+a;++j)        {            for(int k=y+1;k<y+b;++k)                 city[(j-1)*n+k].used=1;//有阻挡的地方将used设为1         }    }}void dp()//动态规划 {    for(int i=1;i<=m;++i)    {        if(!city[(i-1)*n+1].used) city[(i-1)*n+1].value=1;//先确定边界,即第一行和第一列的value值,若没有阻挡则设为1,有阻挡的以及阻挡之后value为0         else break;    }    for(int i=1;i<=n;++i)    {        if(!city[i].used) city[i].value=1;        else break;    }    for(int i=n+2;i<m*n+1;++i)//注意条件的设置,dp的时候跳过了第一行和第一列,因为它们的value值已经确定                 {         if((i-1)%n==0) continue;//跳过第一列         if(!city[i].used)//依次递推每个未被阻挡的节点的value值         {            city[i].value=city[i-1].value+city[i-n].value;          }            }}int main(){    while(cin>>m>>n&&m&&n)    {        m=m+1;        n=n+1;        cin>>B;        readData();        dp();        cout<<city[m*n].value<<endl;//输出到右上角的最短道路数量     }    return 0;}                                 


0 0
原创粉丝点击