zoukankan      html  css  js  c++  java
  • [JZOJ 5811] 简单的填数

    题意:自己搜吧。。。
    思路:
    记二元组\((x,l)\)表示当前为\(x\)且之前有\(l\)个连续数与\(x\)相同。
    并且维护up和low数组表示取到最大/最小值时,连续序列的长度。
    正一遍,反一遍,搞定。
    我排序手抖达成\(a.r and b.r\),调了1小时...

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 200010;
    inline int read () {
    	int q=0,f=1;char ch = getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')f=-1;ch=getchar();
    	}
    	while(isdigit(ch)){
    		q=q*10+ch-'0';ch=getchar();
    	}
    	return q*f;
    }
    struct node {
    	int l,r;
    }up[maxn],low[maxn];
    
    node Max(node a,node b) {
    	if(a.l > b.l||(a.l == b.l && a.r > b.r)) return a;
    	else return b;
    }
    
    node Min(node a,node b) {
    	if(a.l > b.l||(a.l == b.l && a.r > b.r)) return b;
    	else return a;
    }
    
    int n;
    int a[maxn];
    int ans[maxn];
    int w[maxn];
    node t1,t2;
    int main () {
    	freopen("seq.in","r",stdin);
    	freopen("seq.out","w",stdout);
    	n = read();
    	up[0].r = 2;
    	low[0].r = 5;
    	for(int i = 1;i <= n; ++i) {
    		a[i] = read();
    		t1 = up[i - 1];
    		if(t1.r + 1 > 2) {
    			t1.l ++;
    			t1.r = 1;
    		}
    		else t1.r ++;
    		t2.l = a[i];
    		t2.r = 2;
    		if(a[i]) {
    			up[i] = Min(t1,t2);
    		}
    		else up[i] = t1;
    		t1 = low[i - 1];
    		if(t1.r + 1 > 5) {
    			t1.l ++;
    			t1.r = 1;
    		}
    		else {
    			t1.r ++;
    		}
    		t2.r = 1;
    		if(a[i]) {
    			low[i] = Max(t1,t2);
    		}
    		else low[i] = t1;
    	}
    	if(a[1] > 1) {
    		puts("-1");
    		return 0;
    	}
    	if(up[n].r == 1) {
    		up[n].l --;
    	}
    	for(int i = 1;i <= n; ++i) {
    		if(a[i]) {
    			if(a[i] < low[i].l || a[i] > up[i].l) {
    				puts("-1");
    				return 0;
    			}
    			ans[i] = a[i];
    		}
    		if(up[i].l < low[i].l) {
    			puts("-1");
    			return 0;
    		}
    	}
    	ans[n] = up[n].l;
    	w[ans[n]] ++;
    	for(int i = n - 1;i; --i) {
    		if(!a[i]) {
    			ans[i] = min(ans[i + 1],up[i].l);
    			if(w[ans[i]] == 5) {
    				ans[i] --;
    			}
    		}
    		w[ans[i]] ++;
    	}
    	printf("%d\n",ans[n]);
    	for(int i = 1;i <= n; ++i) {
    		printf("%d ",ans[i]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Light oj 1197
    UVA 11426 GCD
    Light oj 1236
    Light oj 1138
    Light oj 1214-Large Division (同余定理)
    Light oj 1234
    HDU
    ZOJ 3469 Food Delivery(* 区间DP 总结)
    二分查找整理
    zoj 3965 Binary Tree Restoring(* dfs)
  • 原文地址:https://www.cnblogs.com/akoasm/p/9579429.html
Copyright © 2011-2022 走看看