XMU 1614 刘备闯三国之三顾茅庐(二) 【逆向思维+二维并查集】
来源:互联网 发布:手机端电影网站源码 编辑:程序博客网 时间:2024/04/25 01:49
1614: 刘备闯三国之三顾茅庐(二)
Time Limit: 1000 MS Memory Limit: 128 MBSubmit: 15 Solved: 5
[Submit][Status][Web Board]
Description
刘备(161年-223年6月10日),字玄德,东汉末年幽州涿郡涿县,西汉中山靖王刘胜的后代。刘备一生极具传奇色彩,早年颠沛流离、备尝艰辛最终却凭借自己的谋略终成一方霸主。那么在那个风云激荡的年代,刘备又是如何从一个卖草鞋的小人物一步一步成为蜀汉的开国皇帝呢?让我们一起拨开历史的迷雾,还原一个真实的刘备。
公元207年冬至,当时驻军新野的刘备在徐庶的建议下,到南阳卧龙岗拜访诸葛亮。这是刘备第二次拜访诸葛亮的故事。三国演义记载的事,由于诸葛亮被朋友邀请不在家中,刘备再次无功而返。然而据我翻阅古籍发现:其实诸葛亮是抛出了如下的问题,想考察刘备本人的谋略、以确定其是否是自己要效忠的那个人:
这是关于战斗的题目。首先我们将战场分割成n*m个区域,诸葛亮每次可以指挥一只军队占领某一行连续的几个格子或者某一列连续的几个格子。诸葛亮会进行q次操作,他想知道每一次操作后,战场被分割成了几个区域?
刘备为人英明神武,但对此类问题也是束手无策,所以这个任务又要交给刘备身边的小跟班——也就是你来解决了。
Input
第一行包含3个整数n,m,q(1<=n,m<=1000,1<=q<=10000)。
接下来有q行,每一行包括4个整数x1,x2,y1,y2(保证有x1=x2或者y1=y2),表示诸葛亮将派遣军队占领(x1,y1)到(x2,y2)这一行/列的区域。
Output
对于每一次操作,输出当前战场被分割成几个区域。
初始时,战场为1个区域。
Sample Input
2 2 2 6
1 3 4 3
2 5 3 5
4 6 4 6
1 6 4 6
Sample Output
3
3
4
3
HINT
样例每一次操作后的战场如下:
Source
by cjf
题目链接:
http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1614
题目大意:
一个N*M的矩形网格,Q个操作,每次操作会输入x1 y1 x2 y2,使(x1,y1)到(x2,y2)的成为障碍(保证x1=x2 或y1=y2,为一行或一列的连续格子)
问每次操作后网格内的联通块数量(不含障碍)。
题目思路:
【逆向思维+二维并查集】
首先将问题反过来做,每次删去一些障碍,求联通块数量。
先将所有数据读入,之后用二维并查集统计联通块数量。
接下来每次都可能删除某些障碍,将新的方格看作新的联通块,然后判断是否会让之前的联通块连通,增减答案。
最后正序输出答案即可。
/**************************************************** Author : Coolxxx Copyright 2017 by Coolxxx. All rights reserved. BLOG : http://blog.csdn.net/u010568270 ****************************************************/#include<bits/stdc++.h>#pragma comment(linker,"/STACK:1024000000,1024000000")#define abs(a) ((a)>0?(a):(-(a)))#define lowbit(a) (a&(-a))#define sqr(a) ((a)*(a))#define mem(a,b) memset(a,b,sizeof(a))const double EPS=1e-8;const int J=10;const int MOD=100000007;const int MAX=0x7f7f7f7f;const double PI=3.14159265358979323;const int N=1004;const int M=10004;using namespace std;typedef long long LL;double anss;LL aans;int cas,cass;int n,m,lll,ans;int num[N][N],sz[N][N];int fa[N][N][2];int f[M];int dx[]={-1,0,1,0};int dy[]={0,1,0,-1};struct xxx{ int x1,y1,x2,y2;}q[M];void zhao(int x,int y,int &fx,int &fy){ if((fa[x][y][0]==x && fa[x][y][1]==y) || (!fa[x][y][0] && !fa[x][y][1])) { fx=x,fy=y; return; } zhao(fa[x][y][0],fa[x][y][1],fx,fy); fa[x][y][0]=fx; fa[x][y][1]=fy;}void print(){ int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) printf("%d ",num[i][j]); puts(""); } puts(""); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) printf("%d,%d ",fa[i][j][0],fa[i][j][1]); puts(""); } puts(""); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) printf("%d ",sz[i][j]); puts(""); } puts("");}int main(){ #ifndef ONLINE_JUDGE freopen("1.txt","r",stdin);// freopen("2.txt","w",stdout); #endif int i,j,k; int x,y,z;// for(scanf("%d",&cass);cass;cass--)// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)// while(~scanf("%s",s)) while(~scanf("%d",&n)) { mem(num,0);mem(sz,0);mem(fa,0);mem(f,0); scanf("%d%d",&m,&cass); for(i=1;i<=cass;i++) { scanf("%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2); if(q[i].x1==q[i].x2) { if(q[i].y1>q[i].y2)swap(q[i].y1,q[i].y2); for(j=q[i].y1;j<=q[i].y2;j++) num[q[i].x1][j]++; } else { if(q[i].x1>q[i].x2)swap(q[i].x1,q[i].x2); for(j=q[i].x1;j<=q[i].x2;j++) num[j][q[i].y1]++; } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { for(k=0;k<4;k++) { x=i+dx[k]; y=j+dy[k]; if(x<1 || x>n || y<1 || y>m || num[i][j] || num[x][y])continue; int fx1,fy1,fx2,fy2; zhao(i,j,fx1,fy1); zhao(x,y,fx2,fy2); if(fx1==fx2 && fy1==fy2)continue; fa[fx2][fy2][0]=fx1; fa[fx2][fy2][1]=fy1; } } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { zhao(i,j,fa[i][j][0],fa[i][j][1]); if(!sz[fa[i][j][0]][fa[i][j][1]] && !num[i][j])f[cass+1]++; sz[fa[i][j][0]][fa[i][j][1]]++; } } for(i=cass;i>1;i--) { f[i]=f[i+1]; if(q[i].x1==q[i].x2) { for(j=q[i].y1;j<=q[i].y2;j++) { num[q[i].x1][j]--; if(num[q[i].x1][j]==0) { f[i]++; for(k=0;k<4;k++) { x=q[i].x1+dx[k]; y=j+dy[k]; if(x<1 || x>n || y<1 || y>m || num[x][y])continue; int fx1,fy1,fx2,fy2; zhao(q[i].x1,j,fx1,fy1); zhao(x,y,fx2,fy2); if(fx1==fx2 && fy1==fy2)continue; fa[fx2][fy2][0]=fx1; fa[fx2][fy2][1]=fy1; f[i]--; } } } } else { for(j=q[i].x1;j<=q[i].x2;j++) { num[j][q[i].y1]--; if(num[j][q[i].y1]==0) { f[i]++; for(k=0;k<4;k++) { x=j+dx[k]; y=q[i].y1+dy[k]; if(x<1 || x>n || y<1 || y>m || num[x][y])continue; int fx1,fy1,fx2,fy2; zhao(j,q[i].y1,fx1,fy1); zhao(x,y,fx2,fy2); if(fx1==fx2 && fy1==fy2)continue; fa[fx2][fy2][0]=fx1; fa[fx2][fy2][1]=fy1; f[i]--; } } } } } for(i=2;i<=cass+1;i++) printf("%d\n",f[i]); //print(); } return 0;}/*// //*/
- XMU 1614 刘备闯三国之三顾茅庐(二) 【逆向思维+二维并查集】
- XMU 1613 刘备闯三国之三顾茅庐(一) 【并查集】
- XMU 1615 刘备闯三国之三顾茅庐(三) 【欧拉函数+快速幂+欧拉定理】
- hdu4496(并查集+逆向思维)
- hdu 4496 D-City(并查集逆向思维)
- HDU4496 D-City(并查集逆向思维)
- BZOJ 1015 星球大战starwar(并查集+逆向思维)
- bzoj1015逆向思维+并查集
- HAUT 1285: 军团再临【并查集*逆向思维】
- XMU 1617 刘备闯三国之汉中之战 【BFS+染色】
- XMU 1611 刘备闯三国之卖草鞋 【贪心】
- XMU 1612 刘备闯三国之桃园结义 【二分】
- 逆向并查集(ZOJ 3261)
- zoj3261(并查集+set) (逆向)
- 二维并查集
- HDU 4496 D-City (并查集的应用)逆向思维
- BZOJ1015 [JSOI2008]星球大战starwar——逆向思维并查集+路径压缩
- luogu P1197 [JSOI2008]星球大战 并查集 逆向思维 邻接表
- NAND flash简单应用
- Spring基础之helloworld
- 构造函数与析构函数
- 关于spark的mllib学习总结(Java版)
- JDBC2和JSP初步--4月23号学习总结
- XMU 1614 刘备闯三国之三顾茅庐(二) 【逆向思维+二维并查集】
- C语言求一个序列的字典序排序
- hiho一下 第147周 小Hi的烦恼
- (2.)javaweb问题之xxx cannot be resolved to a type报错信息(总结)
- LeetCode093 Restore IP Addresses
- My sql数据库的增删改查
- 三十九、SpringBoot配置属性之Migration
- Java之函数递归
- Java DecimalFormat 用法