2016CCPC东北地区大学生程序设计竞赛 - 重现赛 D Coconuts HDU 5925
Coconuts
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 456 Accepted Submission(s): 132
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
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<iomanip>
#include<map>
#include<vector>
#include<queue>
using namespace std;
typedef unsigned long long LL;
const int maxn=400+13;
struct Node{
int x;
int y;
Node(){}
Node(int _x,int _y):x(_x),y(_y){}
Node operator + (const Node & A)
{
return Node(x+A.x,y+A.y);
}
};
Node dir[4]={Node(1,0),Node(-1,0),Node(0,1),Node(0,-1)};
int T;
LL R,C;
int n,x[maxn],y[maxn];
int nx[maxn],ny[maxn];
int a[maxn],sz;
map<int,int> mpx,mpy;
LL grad[maxn][maxn];
int wid[maxn],len[maxn];
bool vis[maxn][maxn];
int nr,nc;
vector<LL> ans;
bool ingrad(Node s)
{
if(s.x<1||s.x>nr) return 0;
if(s.y<1||s.y>nc) return 0;
return 1;
}
LL bfs(Node s)
{
Node u,v;
LL res=0;
queue<Node> que;
que.push(s);
vis[s.x][s.y]=1;
res+=grad[s.x][s.y];
while(!que.empty()){
u=que.front();que.pop();
for(int i=0;i<4;i++){
v=u+dir[i];
if(grad[v.x][v.y]==0) continue;
if(vis[v.x][v.y]) continue;
vis[v.x][v.y]=1;
res+=grad[v.x][v.y];
que.push(v);
}
}
return res;
}
void getans(void)
{
LL tmp=0;
memset(vis,0,sizeof(vis));
ans.clear();
for(int i=1;i<=nr;i++){
for(int j=1;j<=nc;j++){
if(grad[i][j]==0) continue;
if(vis[i][j]) continue;
tmp=bfs(Node(i,j));
ans.push_back(tmp);
}
}
}
int sortunion(int a[],int sz)
{
sort(a,a+sz);
int i,j;
for(i=1,j=0;i<sz;i++){
if(a[i]!=a[j]) a[++j]=a[i];
}
return j+1;
}
void solve(void)
{
if(n==0){
// cout<<R<<C<<endl;
printf("1\n%llu\n",1LLU*R*C);
return ;
}
memset(wid,0,sizeof(wid));
memset(len,0,sizeof(len));
// 离散处理x
int p=1;
memcpy(a,x,sizeof(a));
sz=sortunion(a,n);
// for(int i=0;i<sz;i++){
// printf("%d ",a[i]);
// }
// puts("");
mpx[1]=1;
len[1]=1;
if(a[0]==2){
mpx[a[0]]=++p;
len[p]=1;
}
else if(a[0]>2){
p=p+2;mpx[a[0]]=p;
len[p-1]=a[0]-1-1;
len[p]=1;
}
for(int i=1;i<sz;i++){
if(a[i]==a[i-1]+1){
mpx[a[i]]=++p;
len[p]=1;
}
else{
p=p+2;mpx[a[i]]=p;
len[p]=1;
len[p-1]=a[i]-1-a[i-1];
}
}
if(a[sz-1]==R-1){
mpx[R]=++p;
len[p]=1;
}
else if(a[sz-1]<R-1){
mpx[R]=p+2;
len[p+2]=1;
len[p+1]=R-1-a[sz-1];
p=p+2;
}
nr=p;
//离散处理y
p=1;
memcpy(a,y,sizeof(a));
sz=sortunion(a,n);
mpy[1]=1;
wid[1]=1;
if(a[0]==2){
mpy[a[0]]=++p;
wid[p]=1;
}
else if(a[0]>2){
p=p+2;mpy[a[0]]=p;
wid[p]=1;
wid[p-1]=a[0]-1-1;
}
for(int i=1;i<sz;i++){
if(a[i]==a[i-1]+1){
mpy[a[i]]=++p;
wid[p]=1;
}
else{
p=p+2;mpy[a[i]]=p;
wid[p]=1;wid[p-1]=a[i]-a[i-1]-1;
}
}
if(a[sz-1]==C-1){
mpy[C]=++p;
wid[p]=1;
}
else if(a[sz-1]<C-1){
mpy[C]=p+2;
wid[p+1]=C-1-a[sz-1];
wid[p+2]=1;
p=p+2;
}
nc=p;
fill(grad[0],grad[0]+maxn*maxn,1);
for(int i=0;i<n;i++){
nx[i]=mpx[x[i]];ny[i]=mpy[y[i]];
grad[nx[i]][ny[i]]=0;
// cout<<nx[i]<<" "<<ny[i]<<endl;
}
for(int i=0;i<maxn;i++){
grad[0][i]=grad[nr+1][i]=0;
grad[i][0]=grad[i][nc+1]=0;
}
for(int i=0;i<=nr+1;i++){
for(int j=0;j<=nc+1;j++){
if(grad[i][j]!=0)
grad[i][j]=1LL*len[i]*wid[j];
// printf("%3llu",grad[i][j]);
}
// puts("");
}
getans();
sort(ans.begin(),ans.end());
int all=ans.size();
printf("%d\n",all);
for(int i=0;i<all-1;i++){
printf("%llu ",ans[i]);
}
printf("%llu\n",ans[all-1]);
}
int main()
{
int t=0;
scanf("%d",&T);
while(T--){
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
scanf("%llu %llu",&R,&C);
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d %d",&x[i],&y[i]);
}
printf("Case #%d:\n",++t);
solve();
}
return 0;
}