Codeforces Round #331 (Div. 2)C. Wilbur and Points

题目解释: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\n");
    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\n");
                return 0;
          }
      }
      printf("YES\n");
      for(int i=0;i<n;i++)
        printf("%d %d\n",a[ans[i]].x,a[ans[i]].y);
   }
}
posted @ 2015-11-16 23:09  acliang  阅读(273)  评论(0编辑  收藏  举报