zoukankan      html  css  js  c++  java
  • 2016 长春东北赛---Coconuts(离散化+DFS)

    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=5925

    Problem Description
    TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams about eating. One day, TanBig dreams of a field of coconuts, and the field looks like a large chessboard which has R rows and C columns. In every cell of the field, there is one coconut. Unfortunately, some of the coconuts have gone bad. For sake of his health, TanBig will eat the coconuts following the rule that he can only eat good coconuts and can only eat a connected component of good coconuts one time(you can consider the bad coconuts as barriers, and the good coconuts are 4-connected, which means one coconut in cell (x, y) is connected to (x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1).

    Now TanBig wants to know how many times he needs to eat all the good coconuts in the field, and how many coconuts he would eat each time(the area of each 4-connected component).
     
    Input
    The first line contains apositiveinteger T(T10) which denotes the test cases. T test cases begin from the second line. In every test case, the first line contains two integers R and C, 0<R,C109 the second line contains an integer n, the number of bad coconuts, 0n200 from the third line, there comes n lines, each line contains two integers, xi and yi, which means in cell(xi,yi), there is a bad coconut.

    It is guaranteed that in the input data, the first row and the last row will not have bad coconuts at the same time, the first column and the last column will not have bad coconuts at the same time.
     
    Output
    For each test case, output "Case #x:" in the first line, where x denotes the number of test case, one integer k in the second line, denoting the number of times TanBig needs, in the third line, k integers denoting the number of coconuts he would eat each time, you should output them in increasing order.
     
    Sample Input
    2
    3 3 2
    1 2
    2 1
    3 3 1
    2 2
     
    Sample Output
    Case #1:
    2
    1 6
    Case #2:
    1
    8
     
    Source
     
    Recommend
    wange2014   |   We have carefully selected several similar problems for you:  5932 5931 5930 5929 5928 
     
    题意:有一个R*C的棋盘方格,上面有n个障碍点,求这些障碍点将棋盘分割后的每一个区域的方格数,要求先输出分成的区域数,然后从小到大输出方格数;
     
    思路:要求求出每一个区域的方格数,那么可以DFS深搜求出来,但是R*C太大,会超时,所以必须要进行离散化,减小棋盘; 可以分别用两个数组x[] y[] 存储障碍点的横纵坐标,然后从小到大排序,分别对x  y进行离散,这两个离散过程相同,例如在对x进行离散的过程的中如果x[i]==x[i-1]  那么离散到和x[i-1]同一行 ,如果x[i]==x[i-1]+1 那么离散到x[i-1]对应行的下一行, 其余情况离散到x[i-1]对应行的下一行的下一行;
     
    代码如下:
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N=405;
    LL dx[N],dy[N];///表示每一格压缩的长度;
    bool v[N][N];
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    LL r,c;
    int n;
    
    struct Node{
       long long v,p;
       int id;
    }x[N],y[N];
    
    bool cmp1(const Node s1,const Node s2){
       return s1.v<s2.v;
    }
    bool cmp2(const Node s1,const Node s2){
       return s1.id<s2.id;
    }
    
    LL dfs(int sx,int sy)
    {
        LL sum=dx[sx]*dy[sy];
        v[sx][sy]=true;
        for(int i=0;i<4;i++){
            int nx=sx+dir[i][0];
            int ny=sy+dir[i][1];
            if(nx>0&&ny>0&&nx<=r&&ny<=c)
            if(!v[nx][ny]){
                sum+=dfs(nx,ny);
            }
        }
        return sum;
    }
    
    int main()
    {
        int T,Case=1;
        cin>>T;
        while(T--)
        {
           printf("Case #%d:
    ",Case++);
           scanf("%lld%lld%d",&r,&c,&n);
           for(int i=1;i<=n;i++)
           {
               scanf("%lld%lld",&x[i].v,&y[i].v);
               x[i].id=i;
               y[i].id=i;
           }
           sort(x+1,x+n+1,cmp1);
           sort(y+1,y+n+1,cmp1);
           x[n+1].v=r; y[n+1].v=c;
           x[n+1].id=y[n+1].id=n+1;
           x[0].v=y[0].v=1;
           x[0].id=y[0].id=0;
    
           int tot=1;
           dx[1]=1;
           for(int i=1;i<=n+1;i++)
           {
               if(x[i].v==x[i-1].v){
                  x[i].p=tot;
               }
               else if(x[i].v==x[i-1].v+1){
                  x[i].p=++tot;
                  dx[tot]=1;
               }
               else {
                  x[i].p=tot+2;
                  dx[tot+2]=1;
                  dx[tot+1]=x[i].v-x[i-1].v-1;
                  tot+=2;
               }
           }
           r=tot;
           tot=1;
           dy[1]=1;
           for(int i=1;i<=n+1;i++)
           {
               if(y[i].v==y[i-1].v){
                  y[i].p=tot;
               }
               else if(y[i].v==y[i-1].v+1){
                  y[i].p=++tot;
                  dy[tot]=1;
               }
               else {
                  y[i].p=tot+2;
                  dy[tot+2]=1;
                  dy[tot+1]=y[i].v-y[i-1].v-1;
                  tot+=2;
               }
           }
           c=tot;
    
           memset(v,0,sizeof(v));
           sort(x+1,x+n+1,cmp2);
           sort(y+1,y+n+1,cmp2);
           for(int i=1;i<=n;i++)
              v[x[i].p][y[i].p]=true;
           long long ans[N];
           tot=0;
           for(LL i=1;i<=r;i++)
            for(LL j=1;j<=c;j++)
               if(!v[i][j])
               ans[tot]=dfs(i,j),tot++;
            sort(ans,ans+tot);
            printf("%d
    ",tot);
            for(int i=0;i<tot;i++)
                printf("%lld%c",ans[i],(i+1==tot)?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    [免费解答]赣南师范大学2020年高等代数考研试题参考解答 |
    [免费解答]赣南师范大学2020年数学分析考研试题参考解答 |
    [裴免]裴礼文数学分析练习题免费参考解答-迅速定位版
    免费资料:裴礼文数学分析中的典型问题与方法练习及参考解答
    免费的裴礼文数学分析中的典型问题与方法参考解答, 你接招了么?
    数学专业考研资料pdf版本(今后不再放水印)
    裴礼文数学分析中的典型问题与方法第二版练习题参考解答无水印pdf版本
    谢惠民等数学分析习题课讲义思考题练习题参考题参考解答pdf无水印pdf版
    南京师范大学2018年数学分析考研试题参考解答
    张祖锦的资源库
  • 原文地址:https://www.cnblogs.com/chen9510/p/5936513.html
Copyright © 2011-2022 走看看