题意:
构造一个数组,满足若干条件:
1.
1 l r :在l-r范围内ai <= a(i+1)
2.
0 l r 在l-r范围内有一个 ai > a(i+1)
思路:
先标记所有递增位置, 最后看每个 非递增范围 是不是完全在 递增范围 内, 如果有一个非递增范围完全在 递增范围内 显然不可能构造出, 否则可以构造出
有一个问题:
比如递增范围分别是 1-2, 3-4, 非递增是 2-3,则会判断2-3是完全在1-4内的,但实际上1-4是两个递增范围,为了解决这个问题,我们不标记递增范围的第一个位置,即递增范围分别是2-2, 4-4, 这样标记就可以分清1-4有两个递增范围,检查非递增范围的时候也忽略第一个位置的检查
1 #include <cstdio> 2 #include <iostream> 3 #include <string> 4 #include <queue> 5 #include <cstring> 6 #include <cmath> 7 #include <algorithm> 8 using namespace std; 9 typedef long long LL; 10 typedef unsigned long long ULL; 11 typedef long double LD; 12 typedef pair<int, int> pii; 13 #define mem(a,x,n) memset(a,x,n) 14 #define FOR(i, a, b) for (int i = (a); i <= (b); i++) 15 #define pb push_back 16 #define f first 17 #define s second 18 #define lb lower_bound 19 #define ub upper_bound 20 LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b);} 21 void fast_io() {ios_base::sync_with_stdio(0); cin.tie(0);} 22 const LD PI = 4*atan((LD)1); 23 const int INF = 0x3f3f3f3f; 24 25 const int maxn = 1e5; 26 bool vis[1010]; 27 int n, m, d[1005][2]; 28 void init(){ 29 cin>>n>>m; 30 memset(vis,0,1010); 31 } 32 33 int main() { 34 init(); 35 int cnt=0; 36 while(m--) { 37 int t,l,r; 38 cin >> t >> l >>r; 39 if(t) 40 memset(vis+l+1, 1, r-l);//标记递增范围,注意前边多加一个1 41 else 42 d[cnt][0]=l, d[cnt++][1] = r;//记录非递增范围 43 } 44 FOR(i,0,cnt-1)//检查每一个非递增范围是否在递增范围内 45 { 46 int flag = 0; 47 for(int j = d[i][0]+1; j <= d[i][1]; j++)//注意前边的+1,忽略第一个位置 48 { 49 if(!vis[j]) {//如果有一个点不在递增范围内,我构造的时候就让这个点小于前一个点 50 flag=1; 51 break; 52 } 53 } 54 if(!flag)//所有的点都在递增范围,输出no 55 { 56 cout << "NO\n"; 57 return 0; 58 } 59 } 60 cout << "YES\n"; 61 int s = n+3; 62 FOR(i,1,n) 63 { 64 if(vis[i]) cout << s << (i==n?"":" ");//递增范围全部一样 65 else cout << --s <<(i==n?"":" ");//非递增范围,递减输出 66 } 67 cout << endl; 68 return 0; 69 } View Code
转载于:https://www.cnblogs.com/rookiezjz/p/11201381.html
相关资源:数据结构—成绩单生成器