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(T≤10) 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,C≤109 the second line contains an integer n, the number of bad coconuts, 0≤n≤200 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

2016CCPC东北地区大学生程序设计竞赛 - 重现赛

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:\n",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\n",tot);
        for(int i=0;i<tot;i++)
            printf("%lld%c",ans[i],(i+1==tot)?‘\n‘:‘ ‘);
    }
    return 0;
}
时间: 2024-08-06 11:49:09

2016 长春东北赛---Coconuts(离散化+DFS)的相关文章

hdu 5929 Coconuts 离散化+dfs

Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) 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

2016 大连网赛---Weak Pair(dfs+树状数组)

题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5877 Problem Description You are given a rooted tree of N nodes, labeled from 1 to N. To the ith node a non-negative value ai is assigned.An ordered pair of nodes (u,v) is said to be weak if  (1) u

2016 CCPC 东北地区重现赛

1. 2016 CCPC 东北地区重现赛 2.总结:弱渣,只做出01.03.05水题 08   HDU5929 Basic Data Structure    模拟,双端队列 1.题意:模拟一个栈的操作,并在每次询问时,计算栈项到栈底元素nand位运算的值. 2.总结:思路就是看距离栈底最近的0的后面1的个数的奇偶.试了好多种办法,最后还是双端队列简便.总之,贼恶心的题.. #include<iostream> #include<cstring> #include<cmath

[ An Ac a Day ^_^ ] hdu 5925 Coconuts 离散化+BFS求连通块

东北赛根本就没看懂的的题目…… 也用到了离散化 1e9的x y范围 200个坏点 很典型的离散化数据范围 还是不太为什么离散化的遍历下标都要从1开始…… 所以说只做这道题对离散化的理解还不是很深刻…… 因为可能换一道题又不会了 还是要多做啊 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(x) cerr<<#x<<"=="<<

2015年ACM长春区域赛比赛感悟

距离长春区域赛结束已经4天了,是时候整理一下这次比赛的点点滴滴了. 也是在比赛前一周才得到通知要我参加长春区域赛,当时也是既兴奋又感到有很大的压力,毕竟我的第一场比赛就是区域赛水平,还是很有挑战性的.在接到通知后,我便开始临阵抱佛脚,课也不怎么听了,上课把时间全都用在了看各种算法上,回到实验室便整理模板.开cf练手.在去比赛前,已经将所看过的算法模板都整理好了. 周五上午9点三刻左右,我们便出发了,需要经历12个小时才能到达我们此次的目的地——长春,途中我还将计算几何稍微看了一下.直到晚上11点

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

2016 CCPC 网络赛 A - A water problem 水题,但读题有个坑,输入数字长度很大.. B - Zhu and 772002 题意:给出n个数(给出的每个数的质因子最大不超过2000),选出多个数相乘得b.问有多少种选法让b 为完全平方数. tags:高斯消元,求异或方程组解的个数.   好题 每个数先素数分解开.  对于2000以内的每个素数p[i],这n个数有奇数个p[i]则系数为1,偶数个则系数为0,最后n个数的p[i]系数异或和都要为0才会使得最后的积为完全平方数.

HDU 5923 Prediction(2016 CCPC东北地区大学生程序设计竞赛 Problem B)

题目链接  2016 CCPC东北地区大学生程序设计竞赛 B题 题意  给定一个无向图和一棵树,树上的每个结点对应无向图中的一条边,现在给出$q$个询问, 每次选定树中的一个点集,然后真正被选上的是这些点以及这些点的所有祖先. 只有标号在树中真正被选上的点代表的这些原图中的边是存在的,这样就构成了一个新的图.求这个图的连通块个数. dfs整棵树,记$f[x]$为若$x$以及$x$的所有祖先被选上,那么构成的新的图的并查集) 这个实现比较简单,搜索的时候打上标记,回来的时候撤销即可. 这样预处理的

UVALive 6663 Count the Regions --离散化+DFS染色

题意:给你n(n<=50)个矩形(左上角坐标和右下角坐标),问这些矩形总共将平面分成多少个部分.坐标值可能有1e9. 分析:看到n和坐标的范围,容易想到离散化,当时就没想到离散化以后怎么判断区域个数.后来看别人代码才知道,可以将边界上的点vis赋为1,那么枚举所有哈希后的平面上的点,遇到一个vis=0的点就从这点一直搜过去,搜到边界自动会停止了,因为边界vis=1,并且ans++,就可以了.真是太弱.. 代码: #include <iostream> #include <cstdi

HDU 4815 2013长春现场赛C题

C - Little Tiger vs. Deep Monkey Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4815 Description A crowd of little animals is visiting a mysterious laboratory ? The Deep Lab of SYSU. "Are y