【Codeforces Round 331 (Div 2)C】【脑洞 SET贪心写法】Wilbur and Points 锯齿图形差值编号,右上角的最大
来源:互联网 发布:北京宽带哪个好 知乎 编辑:程序博客网 时间:2024/06/08 05:53
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}const int N=2e5+10,M=0,Z=1e9+7,ms63=1061109567;const int BAS=1e5;int n;int x,y;pair<int,int>ans[N];set<pair<int,int>>sot[N],point;bool check(){for(int i=1;i<=n;++i){int k;scanf("%d",&k);k+=BAS;if(sot[k].size()==0)return 0;int x=sot[k].begin()->first;int y=sot[k].begin()->second;sot[k].erase(sot[k].begin());if(x&&!point.count(MP(x-1,y)))return 0;if(y&&!point.count(MP(x,y-1)))return 0;point.insert(MP(x,y));ans[i]=MP(x,y);}return 1;}int main(){scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d%d",&x,&y);sot[y-x+BAS].insert(MP(x,y));}if(check()){puts("YES");for(int i=1;i<=n;++i)printf("%d %d\n",ans[i].first,ans[i].second);}else puts("NO");return 0;}/*【trick&&吐槽】这题可谓是,极富思维价值,非常有意义!【题意】给你一个集合,集合中包含n(1<=n<=1e5)个点。每个点的坐标都是[0,1e5]范围的。而且,如果点(x,y)在这个集合中,那对于(xx,yy),0<=xx<=x&&0<=yy<=y,(xx,yy)也会在这个集合中。我们会告诉你,会依次输出,这个集合中的所有点。现在,我们要对集合中的所有点做编号操作,n个点的编号依次为从1到n。如果一个点(x,y)被编号为p,那对于(xx,yy),0<=xx<=x&&0<=yy<=y的所有点(xx,yy),(xx,yy)的编号要严格比p小。现在,我们要你对这n个点染色。定义w(point)=point.y-point.x,也就是这个点的纵坐标-横坐标。编号为1,2,3,4,5,...,n的n个点。需要对应着w()值分为为k1,k2,k3,k4,k5,...,kn。我们会输出这个k[]数列。现在,让你判定我们是否可以成功给所有点编号。如果可以,则输出YES,然后按照k[]数列的顺序依次输出其所对应的所有点。否则,则输出NO。【类型】脑洞【分析】有一种可行的做法是——我们对于每个点,求出这个点的坐标差值,把这个点push_back到这个差值的vector中。然后我们处理询问的时候,在询问中,有(编号,差值)这两个信息。我们从差值的vector中,取出点,如果这个点之间没有编号过。而且比这个点小的点都编号过了。那么我们给这个点编号。会不会有多个点同时满足这个条件,且对应着合法的方案呢?显然,是不会的。因为,题目中给出的点的集合,其实是一个呈阶梯状下降的形状。同样的差值,对应的是y=x+b的一条线,这条线上,肯定最多只有一个点,满足这个点左下角的所有点都被编号过且自己没有编号过的条件。于是我们通过vector和map,就解决了这道题。它的时间复杂度是多少呢?最坏情况,大概是很多点都push_back到同一个vector中。这样,我们的暴力的时间复杂度就可达vector.size()^2级别。然而,因为题目中所说的一个点如果选就会选这个点左下角全部点。于是,vector.size()最多不过是2000,于是这种做法的AC是合理的,时间复杂度取决于map,是O(nlogn)。然而,这个速度还是有些慢的。我们发现,每次我们从vector中取点,也花费了大量时间。不如我们用set来存放每个差值的点。这样,当我们处理到(编号,差值)的时候,在同样的差值的点中,我们一定是选取当前未编号的点中位置最小的一个做染色。【时间复杂度&&优化】O(nlogn)【数据】60 00 10 20 30 40 50 1 2 3 4 5;*/
1 0
- 【Codeforces Round 331 (Div 2)C】【脑洞 SET贪心写法】Wilbur and Points 锯齿图形差值编号,右上角的最大
- 巧妙地利用STL map set pair 贪心+排序 Codeforces Round #331 (Div. 2)C. Wilbur and Points
- Codeforces Round #331 (Div. 2) C. Wilbur and Points
- Codeforces Round #331 (Div. 2) C. Wilbur and Points
- Codeforces Round #331 (Div. 2) C. Wilbur and Points
- Codeforces Round #331 (Div. 2)-C. Wilbur and Points
- Codeforces Round #331 (Div. 2) C. Wilbur and Points 贪心+排序
- codeforces#331-C - Wilbur and Points-set/贪心乱搞
- Codeforces Round #331 (Div. 2)C. Wilbur and Points(模拟+STL)
- Codeforces Round #331 (Div. 2)——C. Wilbur and Points
- Codeforces Round #331 (Div. 2)-C-Wilbur and Points(STL容器)
- Codeforces Round #331 (Div. 2) B. Wilbur and Array (贪心)
- Codeforces 596 C Wilbur and Points【贪心】
- Codeforces Round #331 (Div. 2)-Wilbur and Array(贪心模拟)
- Codeforces Round #331 (Div. 2) A. Wilbur and Swimming Pool (判断组成最大矩形)
- Codeforces 596C Wilbur and Points 【贪心 + sort】
- Codeforces Round #331 (Div. 2) A. Wilbur and Swimming Pool
- Codeforces Round #331 (Div. 2) B. Wilbur and Array
- 【转】sprintf
- 库里可超科比单场81分 萌神46投能砍100分?
- 第十二周项目2 操作用邻接表储存的图
- 最全Pycharm教程(7)——虚拟机VM的配置
- Win7电脑中外网网卡共享
- 【Codeforces Round 331 (Div 2)C】【脑洞 SET贪心写法】Wilbur and Points 锯齿图形差值编号,右上角的最大
- TS科普18 节目映射表PMT
- UEFI怎么用 UEFI安全启动设置添加方法步骤图解
- 深入分析JavaWeb Item5 -- Servlet开发
- TCP,IP详解,卷一:协议学习笔记之第二章链路层
- otsu算法实现(基于opecv2.0版本)
- 标题:解决问题越多,你就会变得很富有
- mkdosfs
- UEFI安全启动怎么关闭 关闭UEFI启动项的方法图解