Educational Codeforces Round 67 (Rated for Div. 2) C

  • 题目大意: 有一个序列但不知道具体的数值,给出一些提示 \(t_i,l_i,r_i\),\(t_i=0\)表示区间\(l_i\)\(r_i\)有序,\(t_i=1\)则为无序
  • 思路: 先构造一个全为1的序列,这样可以满足所有\(t_i=1\)的情况,然后对每个\(t_i=0\)先判断区间是否存在\(t_i=0\)的区间包含,如果包含则无法满足.否则用一个标记数组表示该位置元素应该跟后一个元素保持有序,无约束和已经无序.对每个\(t_i=0\)在其区间内找到一个无约束的元素将其改变成无序即可(若区间内已经有无序的元素则不需要改变)
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#define ll long long 
#define FOR(i,n) for(int i =1; i <= n;++i ) 
#define FOR0(i,n) for(int i =0; i < n;++i )  
#define inf 0x3f3f3f3f
using namespace std; 


const int maxn = 1010;
int n,m;

struct node{
	int t,l,r;
}b[maxn];
int arr[maxn];
int vis[maxn];

int cmp(node x,node y){
	if(x.t == y.t){
		if(x.l == y.l){
			return x.t==1?x.r < y.r:x.r>=y.r;
		}
		return x.t==1? x.l < y.l: x.l>=y.l ;
	}
	return x.t > y.t;
}

int main(){
	cin >> n >> m;
	for(int i=1;i<=m;++i){
		cin >> b[i].t >> b[i].l >> b[i].r;
	}
	for(int i=1;i<=n;++i){
		arr[i] = 1;
	}
	sort(b+1,b+1+m,cmp);
	int r=0;
	bool sign= false;
	for(int i=1;i<=m;++i){
		if(!b[i].t){
			r = i;
			break;
		}
		for(int j=b[i].l;j<b[i].r;++j){
			vis[j] = 1;
		}
	}
	if(r==0){
		cout <<"YES" <<endl;
		for(int i=1;i<=n;++i)	cout << arr[i] << ' ';
		cout << endl;
	}else{
		for(int i=r;i<=m;++i){
			for(int j=1;j<r;++j){
				if(b[j].l<=b[i].l && b[j].r>=b[i].r){
					sign = true;
					break;
				}
			}
			if(sign) 	break;
			int j;
			for(j=b[i].l;j<b[i].r;++j){
				if(vis[j]==-1)	break;
				else if(vis[j]==0){
					vis[j] = -1;
					arr[j] = arr[j+1]+1;
					break;
				}
			}
			if(j==b[i].r){
				sign = true;	break;
			}
		}
		
		if(sign) cout << "NO" <<endl;
		else{
			cout <<"YES"<<endl;
			for(int i=1;i<=n;++i){
				cout << arr[i] << ' ';
			}
			cout << endl;
		}
	}
	
	
	return 0;
}
  • 总结: 总体思路还是贪心,不过在处理\(t_i=0\)时要从区间左端点从大到小处理,否则后面的处理会覆盖到前面的结果(被hack掉了QAQ)
posted @ 2019-07-02 01:00  新新人類  阅读(132)  评论(0编辑  收藏  举报