hdu5925 Coconuts 离散化 dfs搜索 TWT Tokyo Olympic 1combo-1

来源:互联网 发布:域名网 编辑:程序博客网 时间:2024/06/05 23:55

Coconuts

Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 300 Accepted Submission(s): 93


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
23 321 22 13 312 2

Sample Output
Case #1:21 6Case #2:18

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

离散化得很巧妙,int和longlong转换wa了好几回

先吃点东西回宿舍再写。。。


。。。。。。。。。。

Steins;Gate 0  。。。。。

太他妈好看了!!!!!!!!!!!!!!!!!

果然取名叫kyoma是正确的选择(哭)

红莉栖。。。。

进入正题:

题目给了我们一个图,几个点表示坏椰子,没有给出的点就是好椰子,让我们找出这个图有多少个联通块(上下左右相连认作联通),并且各个联通块中有多少个格子

如果数据量小的话当然很好做啦,典型的dfs嘛。。。但是题目给的图的边长是1e9.。。肯定有特殊的姿势

(duang)离散化(特技)(duang)

开什么玩笑,老子只知道一维的离散化啊,二维的是个啥玩意儿啊

早上的概率论受zyyyyy执导后来到机房研究。。。


如上图wwww方格里打叉的是坏椰子,而其他上色区域都是好椰子,那么每个颜色不同的区域我们都可以把它变成一格,为什么要这么做呢,因为题目已经说了最多只有200个坏椰子的点,所以将好椰子格子浓缩的话就可以将将边长减小至2*200+1。。。

具体的实现方法,分别在x,y轴对好、坏椰子做编号,如下图:


连续的好椰子区间记录下它的长度,算作一个单位长度,x轴坐标想等的坏椰子视为一个单位长度,仅有一个坏椰子也视作一个单位长度

同样对y轴也是如此,这样对于每个区域,将其连续的好椰子区域压缩为一格。


经过以上变换就将一个6*6的格子图压缩成6*5的图。。。。只不过其中有一列代表了这个格子上有两个好椰子!

虽然这样看变化很微小,但是拿到1e9对200个点这个数量级上就很可观了

图画的好丑。。。。讲得也不太明白。。。。

详细还是看代码吧

其中change数组是储存变化后其x/y的边长,save_number是存着改点的编号


#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <cmath>using namespace std;const int maxn=2000;struct unit{int  value;int position;bool operator<(const unit a) const{return value<a.value;} };unit x[maxn];unit y[maxn];int changex[maxn];int changey[maxn];int save_number_x[maxn];int save_number_y[maxn];int r,c;bool vis[maxn][maxn];int move_x[4]={0,0,1,-1};int move_y[4]={-1,1,0,0};long long dfs(int x,int y){long long ans=(long long)changex[x]*(long long)changey[y];vis[x][y]=false;for(int i=0;i<4;i++){int dx=x+move_x[i];int dy=y+move_y[i];if(dx>=1&&dx<=r&&dy>=1&&dy<=c&&vis[dx][dy]){ans+=dfs(dx,dy);}}return ans;}int main(){int t;scanf("%d",&t);int rnd=1;int i,j,k,n;while(t--){scanf("%d%d%d",&r,&c,&n);for(i=1;i<=n;i++){scanf("%d%d",&x[i].value,&y[i].value);x[i].position=i;y[i].position=i;}sort(x+1,x+1+n);sort(y+1,y+1+n);x[n+1].value=r;y[n+1].value=c;x[n+1].position=n+1;y[n+1].position=n+1;x[0].value=1;y[0].value=1;changex[1]=1;changey[1]=1;int the_number=1;for(i=1;i<=n+1;i++){if(x[i].value==x[i-1].value){save_number_x[x[i].position]=the_number;changex[the_number]=1;}else if(x[i].value==x[i-1].value+1){the_number++;save_number_x[x[i].position]=the_number;changex[the_number]=1;}else{save_number_x[x[i].position]=the_number+2;changex[the_number+1]=x[i].value-x[i-1].value-1;changex[the_number+2]=1;the_number+=2;}}r=the_number;the_number=1;for(i=1;i<=n+1;i++){if(y[i].value==y[i-1].value){save_number_y[y[i].position]=the_number;changey[the_number]=1;}else if(y[i].value==y[i-1].value+1){the_number++;save_number_y[y[i].position]=the_number;changey[the_number]=1;}else{save_number_y[y[i].position]=the_number+2;changey[the_number+1]=y[i].value-y[i-1].value-1;changey[the_number+2]=1;the_number+=2;}}c=the_number;memset(vis,true,sizeof(vis));for(i=1;i<=n;i++){vis[save_number_x[i]][save_number_y[i]]=false;}vector<long long> result;for(i=1;i<=r;i++){for(j=1;j<=c;j++){if(vis[i][j]){result.push_back(dfs(i,j));}}}sort(result.begin(),result.end());printf("Case #%d:\n", rnd);printf("%d\n", result.size());  for(i=0;i<result.size();i++){printf("%lld%c", result[i], i==result.size()-1?'\n':' '); }rnd++;}        return 0;}



0 0
原创粉丝点击