题目解释:n个点对,n个数,要求求出是否存在一个增序列满足答案,并输出。
(集合规则:如果(x,y)在集合里,那么(0,0)到(x,y-1),(x-1,y)也在集合里
输入的时候也是)
首先怎么暴力怎么来,我们先对n个点对进行分类(根据差值分类),然后每一类分别从小到大排序。然后目前的解就是一次填充n个数,因为小的肯定在大的前面被填充,否则就不符合集合的定义。
然后进行判断,因为数据点没有突变,只要严格意义上不比前一个数大就行,因为都是连续的数据段。
#include<cstdio> #include<algorithm> #include<cmath> #include<map> #include<iostream> #include<vector> #include<cstring> #include<queue> #include<string> using namespace std; int n; struct node1 { int x,y,c; }a[100005]; int f[200005]; int c[100005]; vector<int> g[200005]; int ans[100005]; bool cmp1(const int xx,const int yy) { if(a[xx].x<a[yy].x) return 1; return 0; } int main() { //freopen("input.txt","r",stdin); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&a[i].x,&a[i].y); a[i].c=a[i].y-a[i].x; g[a[i].c+100000].push_back(i); } for(int i=0;i<=200002;i++) sort(g[i].begin(),g[i].end(),cmp1); int t; int flag=1; for(int i=0;i<n;i++){ scanf("%d",&t); c[i]=t; if(flag){ if(f[t+100000]==g[t+100000].size()) {flag=0; break; } ans[i]=g[t+100000][f[t+100000]]; f[t+100000]++;} } if(!flag) { printf("NO "); return 0; } else { for(int i=1;i<n;i++) { int t1=a[ans[i]].x; int t2=a[ans[i]].y; int t3=a[ans[i-1]].x; int t4=a[ans[i-1]].y; if((t3>t1&&t4>=t2)||((t3>=t1&&t4>t2))) { printf("NO "); return 0; } } printf("YES "); for(int i=0;i<n;i++) printf("%d %d ",a[ans[i]].x,a[ans[i]].y); } }