[清橙A1363][THUSC 2012]水位(并查集+高精度压位)
来源:互联网 发布:55开淘宝店地址服装 编辑:程序博客网 时间:2024/05/23 01:33
题目链接
http://www.tsinsen.com/A1363
题目大意
给一个
思路
这个题实在太神了,我跪了半个上午+一个下午才AC,跪跪跪
首先我们可以想到,可能由于某些格子组成的“墙”的阻挡,水被分成了若干个小水池,这些水池之间是互不影响的,一个水池水位高一点、低一点不会另一个水池造成任何影响,除非水位上涨漫过了那些墙,这样几个水池就会连在一起。
那么我们可以模拟水位上涨的过程,假设最开始水位高度为最高的那个格子的高度,并且水从最高的那个格子像泉水一样源源不断地流出来。先对
后记
其实这个题目思路并不难,然而丧病的是这个题需要写个高精度,而且最终答案的数字特别大,这意味着需要写个压位,然后我因为高精度刚开始没压位,一直没发现为什么WA,然后补上压位(
感谢http://www.cnblogs.com/Randolph87/p/3769796.html提供此题的pascal标程供我对拍查错
代码
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 103#define LEN 3000#define calc(i,j) (((i)-1)*n+(j))#define BASE 10000000using namespace std;typedef long long int LL;int n,m;struct Hugeint{ LL num[LEN]; int len; void print() { printf("%lld",num[len]); for(int i=len-1;i>=1;i--) printf("%07lld",num[i]); }}ans[MAXN*MAXN],a,b,t;struct Point{ int x,y,num;}points[MAXN*MAXN];bool inMap(int x,int y){ if(x<1||x>n||y<1||y>n) return false; return true;}Hugeint operator+(Hugeint a,LL b){ a.num[1]+=b; for(int i=1;i<=a.len;i++) { a.num[i+1]+=a.num[i]/BASE; a.num[i]%=BASE; } while(a.num[a.len+1]) { a.len++; a.num[a.len+1]+=a.num[a.len]/BASE; a.num[a.len]%=BASE; } return a;}Hugeint operator*(Hugeint a,Hugeint b){ Hugeint c; memset(c.num,0,sizeof(c.num)); c.len=a.len+b.len-1; for(int i=1;i<=a.len;i++) for(int j=1;j<=b.len;j++) c.num[i+j-1]+=a.num[i]*b.num[j]; for(int i=1;i<=c.len-1;i++) { c.num[i+1]+=c.num[i]/BASE; c.num[i]%=BASE; } while(c.num[c.len]>=BASE) { c.num[c.len+1]=c.num[c.len]/BASE; c.num[c.len]%=BASE; c.len++; } return c;}int map[MAXN][MAXN];int f[MAXN*MAXN];int h[MAXN*MAXN]; //h[i]=联通块i的水位高度int findSet(int x){ if(f[x]==x) return f[x]; return f[x]=findSet(f[x]);}int xx[]={1,-1,0,0},yy[]={0,0,1,-1};bool cmp(Point a,Point b){ if(map[a.x][a.y]==map[b.x][b.y]) { return a.num<b.num; } return map[a.x][a.y]<map[b.x][b.y];}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&map[i][j]); h[calc(i,j)]=map[i][j]; points[calc(i,j)].x=i,points[calc(i,j)].y=j,points[calc(i,j)].num=calc(i,j); } for(int i=1;i<=n*n;i++) //初始化第i号格子 { f[i]=i; ans[i].len=ans[i].num[1]=1; } sort(points+1,points+n*n+1,cmp); //!!!!!! for(int i=1;i<=n*n;i++) //枚举第i号格子 for(int dir=0;dir<4;dir++) { int nowx=points[i].x,nowy=points[i].y; int nextx=nowx+xx[dir],nexty=nowy+yy[dir]; if(!inMap(nextx,nexty)) continue; //!!!!!!! int roota=findSet(calc(nowx,nowy)),rootb=findSet(calc(nextx,nexty)); //roota是(nowx,nowy)所属联通块,rootb是(nextx,nexty)所属联通块 if(h[roota]>=h[rootb]&&roota!=rootb) //a联通块水位比b联通块水位高,而且它们并不是联通的 { ans[rootb]=ans[rootb]+(h[roota]-h[rootb]); //那么b联通块的方案数要加上两个联通块之间的水位差 ans[roota]=ans[roota]*ans[rootb]; //两个联通块联通后,新联通块的方案数是两个老联通块方案数的乘积(乘法原理) f[rootb]=roota; //并查集合并两个联通块 } } ans[findSet(1)]=ans[findSet(1)]+(m-map[points[n*n].x][points[n*n].y]);//所有的联通块都在一起,也就是整个地图上没有干旱的高地了,那么要加上剩余的方案(一直灌水到水位上升至m) ans[findSet(1)].print(); printf("\n"); return 0;}
- [清橙A1363][THUSC 2012]水位(并查集+高精度压位)
- [BZOJ2959][清橙1379]长跑-LCT-并查集
- UVA -2232(并查集 + 位运算)
- UVa 10158 并查集+位操作
- 压位高精度系统
- 压位高精度模板
- 高精度乘法(压位)
- {模板}高精度压位
- 压位高精度
- 高精度压位1
- 高精度压位
- 【模板】压位高精度
- 高精度压位模板
- 压位高精度模板
- poj 1164 The Castle 位运算+并查集/搜索
- [NOIP模拟题][位运算][建模][并查集]
- 【APIO2011T1】方格染色-并查集+位运算推导
- hdu1250(高精度压位)
- Golang日志--Seelog的简单用法
- 程序实现自启动的方式总结
- IOS多张图片合成一个视频
- IOS视频添加背景音乐同时保留原音
- Windows系统程序设计之结构化异常处理
- [清橙A1363][THUSC 2012]水位(并查集+高精度压位)
- 数组第二十五课,多维数组,基本语法,内存分析
- c++TCP连接
- BZOJ 1854 游戏(二分图匹配)
- RPC之异构方案---webservice
- Using Swift with Cocoa and Objective-C
- [Python]Python3.3 xlwt3 安装及使用报错解决办法汇总
- 线程使用
- 关于typedef的用法总结