染色问题:在一维坐标轴上(最右端为M),有N个(a,b,c)的染色操作,即把在坐标(a,b)之间的线段染成颜色c.最后来求解一系列问题。如:最长的颜色为C的区间,每种颜色的总长度,每种颜色的区间段数等等。
矩形切割问题:在二维坐标轴上,给出N个矩形,这N个矩形可能相互包含,交叉,分离。最后求解一系列问题。如N个矩形所覆盖的面积,相交的面积等。
先来看染色问题,如果考虑坐标轴的长度为10^9数量级,而染色的操作数为1^3。那么这类问题往往需要先将连续的长度为M的区间离散化为P个染色区间.P往往是N级的。这样就将计算量大大缩短。
如题zoj_2301,M=2^31-1,N<2000,[1 4][8 11] [3 5]这3个区间的表达方式不是端点类型([1 4]表达的是从第一个到第四个),所以需要转化为[0 4][7 11][2 5]([0 4]表达的是在坐标0和4之间)。
有了上述的初始话,接下来就可以是离散化了,读取区间的所有端点,去除重复,再排序,得到一个序列{0,2,4,5,7,11}(可以用set方便实现).最后,对序列中每相邻的两个节点构造对于的区间,最后得到[0,2][2,4][4,5][5,7][7,11]这5个区间,之后的计算由此就可以大量简化。如果离散化之后的区间数为E,那么之后操作的复杂度为E*N,如果再使用线段树,可以优化为log(e)*N.
再来看矩形切割问题,如果考虑到坐标所取的范围为M,10^9数量级,而给出的的矩形数为N=10^2.那么考虑延长每个矩形的每一条边,最后可以将坐标平面的分割成一个网格,而网格的数量级为N*N=10^4远小于10^9,由此可以简化计算。同样,再使用一维线段树可以将问题简化为NlogN,使用二维线段树可以简化为logNlogN具体见zoj_1128
zoj_2301
#include<iostream> #include<cstdio> #include<set> #include<vector> using namespace std; class line { public: int left; int right; char c; line(int left,int right,char c) { this->left=left; this->right=right; this->c=c; } }; int l,r,n,size; char c; set<int>map; vector<line>v; bool check(int l,int r) { char c='b'; for(int i=0;i<size;i++) { if(l>=v[i].left&&r<=v[i].right) c=v[i].c; } if(c=='w') return true; else return false; } int main() { freopen("e:\\zoj\\zoj_2301.txt","r",stdin); while(scanf("%d",&n)!=EOF) { map.clear(); while(n--) { scanf("%d %d %c",&l,&r,&c); v.push_back(line(l-1,r,c)); map.insert(l-1); map.insert(r); size=v.size(); } int max=-1; int mid=0; bool con=false; int east=-1; for(set<int>::iterator it=map.begin();it!=map.end();it++) { int left=*it; it++; if(it==map.end()) { it--; break; } int right=*it; it--; if(check(left,right)) { con=true; mid+=(right-left); if(mid>max) { max=mid; east=right; } } else { con=false; mid=0; } } if(max==-1) printf("Oh, my god\n"); else printf("%d %d\n",east-max+1,east); } }
zoj_1128
#include<iostream> #include<cstdio> #include<vector> #include<set> using namespace std; double lx,ly,rx,ry; int n,size; class rect { public: double lx,ly,rx,ry; rect(double lx,double ly,double rx,double ry) { this->lx=lx; this->ly=ly; this->rx=rx; this->ry=ry; } }; vector<rect>v; set<double>x; set<double>y; bool cover(rect a) { for(int i=0;i<size;i++) { if(a.lx>=v[i].lx&&a.rx<=v[i].rx&&a.ly>=v[i].ly&&a.ry<=v[i].ry) { return true; } } return false; } int main() { int num=1; freopen("e:\\zoj\\zoj_1128.txt","r",stdin); while(cin>>n&&n) { v.clear(); x.clear(); y.clear(); while(n--) { cin>>lx>>ly>>rx>>ry; x.insert(lx); x.insert(rx); y.insert(ly); y.insert(ry); v.push_back(rect(lx,ly,rx,ry)); } double square=0; size=v.size(); for(set<double>::iterator it=x.begin();it!=x.end();++it) { lx=(*it); if(++it==x.end()) break; rx=(*it); --it; for(set<double>::iterator it2=y.begin();it2!=y.end();++it2) { ly=(*it2); if(++it2==y.end()) break; ry=(*it2); --it2; if(cover(rect(lx,ly,rx,ry))) square+=(rx-lx)*(ry-ly); } } cout<<"Test case #"<<num<<endl; printf("Total explored area: %.2lf\n",square); printf("\n"); ++num; } }
发表评论
-
图的割点tarjan---zoj_1119
2011-10-24 23:00 1231http://acm.zju.edu.cn/on ... -
BFS与双向BFS---zoj_1505
2011-10-09 17:14 1642http://acm.zju.edu.c ... -
静态treap+线段树---zoj_2112
2011-09-29 23:06 1708http://acm.zju.edu ... -
NIM博弈游戏,SG函数---zoj_3084,zoj_2083
2011-09-23 23:00 1316Nim游戏是两个人进行的游戏有如下规则: ... -
多重背包--zoj_2156
2011-09-14 11:10 863首先介绍经典的三种背包问题,0-1背包,完全 ... -
模式串匹配---KMP
2011-08-31 20:49 1277朴素的的模式串匹配算法通常要在向前移动文本指针 ... -
八数码问题(A*&&双向BFS)---zoj_1217
2011-08-30 22:13 1664题目地址:http://acm.zju.edu.cn/onli ... -
ac自动机以及它上面的DFA
2011-08-08 23:04 2479AC自动机(Aho-Corasick)主要用 ... -
二分图最大匹配(匈牙利算法)--zoj1516,1525,2223
2011-07-20 22:36 1185二分图G(E,V)将点集合V分成两个部分L,R ... -
网络最大流(EK)---zoj_1734
2011-07-19 16:34 2130网络最大流是图论中的一个典型问题,为了精确的定 ... -
trie和前缀检查---zoj_2876
2011-07-13 23:03 865trie树是一种多叉树,广泛用于字典检索。如 ... -
位图bitmap
2011-07-13 21:08 913bitmap是一种广泛使用的数据结构,主要用在 ... -
LAC和RMQ的转化---zoj_3195
2011-07-12 22:35 1072我擦。。纠结了好久啊,从SF到TLE,先总结2 ... -
LAC的tarjan(离线)算法---zoj_1141
2011-07-08 17:52 1658LCA就不解释了,这里主要再次复习一下LC ... -
笛卡尔树以及treap---zoj_2243
2011-07-07 15:52 2838zoj_2243笛卡 ... -
线段树---zoj_1610
2011-06-22 21:06 743线段树是一种二叉树的拓展,在线段树每个节点中 ... -
快速排序(qsort)
2011-06-16 17:03 776快速排序是一种高效的非稳定排序,它的基本思路 ... -
斐波那契散列
2011-06-16 16:38 3072斐波那契散列法其实是一种特殊的乘法散列,先来看乘法 ... -
强连通分支(scc)---tarjan
2011-06-15 16:17 1283本文大量 ... -
单源最短路径SPFA---zoj3146
2011-06-09 15:25 940针对Bellman-Ford算法效率比较低 ...
相关推荐
zoj在线评测系统前台和后台源代码,包括比赛用的客户端源代码
这是一份ZOJ的ACM题解,包含大多数题目的AC程序,是学习算法的好东西~
zoj吐血制作,希望大家喜欢
最近在acm.zju.edu.cn上通过的题目的代码,都是比较有价值的题目
zoj网站中多个练习的c++解答,文件名即为题目序号。经本人测试可以使用,主要为动态规划方面的问题,希望给初学者提供帮助。
zoj4041正确题解源代码,以及运行程序
ZOJ 1055 Oh, Those Achin Feet.bfs求最短路径.
acm中zoj1002的可运行C++程序
zoj的代码实现,很好,而且很全面,全部实现。
一个非常非常非常非常实用的zoj结题代码
能AC 通过的c++代码,包括zoj1002,1091,1789
浙江大学ZOJ源码题解,按照题目类型和难易分类。
问题:枫教授在一所大学教数学,他发现了一个函数,用于获得一个表达式的操作数的目的,函数命名op(i,e)可以描述如下:
本资源是对线段树操作比较完整的操作,包括线段树的动态插入,动态删除和维护,可以查询区段的最大值,最小值,完成线段树的基本操作。
ZOJ上的一些水题,4.16浙江省程序设计竞赛的题目
zoj 2536 这个不是用贪心做的
zoj上的3607Lazier Salesgirl AC代码及一些注释。贪心算法
浙大acm OJ1204,自己做的,已经AC 分享一下,若有更好的算法可以教教我
ZOJ解题报告ZOJ解题报告ZOJ解题报告ZOJ解题报告
ZOJ3180 ACM题目 算法的实现 浙江大学ZOJ