JZOJ5811. 【NOIP提高A組模擬2018.8.13】簡單的填數
阿新 • • 發佈:2018-12-31
Data Constraint
對於 30% 的資料,n ≤ 1000;
對於另外 30% 的資料,資料保證隨機生成;
對於 100% 的資料,2 ≤ n ≤ 2 × 10^5 , 0 ≤ ai ≤ 10^5。
題解
這個很顯然是特殊構造,
設一個二元組(x,l)擺在這個位置是x,而且這個是連續的第l個x。
設上界為up,下界為down。
因為要使得最終最大,所以up就是到l=2的時候就x++,
而相反down要儘可能小,所以只有當l=5時才x++。
如果遇到一個已經填了數的位置
就將up跟去min,因為填2之後就下一個位置就可以加1了,
那麼down就跟去max,因為填1之後,還可以填更多的x。
判斷合法就很簡單,
1、上界跟下界之間沒有數可以填,
2、原來已經有數的位置並不在上下界之間。
3、第一個位置填的不是1
最後,就是將整個序列還原,從最後一個位置開始,
每個數跟它後面一個數,還有上界去min,如果這個數出現的次數超過5,
就x–。
code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#include <math.h>
#include <time.h>
#define ll long long
#define N 200003
#define M 103
#define db double
#define P putchar
#define G getchar
#define inf 998244353
#define pi 3.1415926535897932384626433832795
using namespace std;
char ch;
void read(int &n)
{
n=0;
ch=G();
while ((ch<'0' || ch>'9') && ch!='-')ch=G();
ll w=1;
if(ch=='-')w=-1,ch=G();
while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
n*=w;
}
struct node
{
int x,l;
}up[N],down[N],t,tt;
node max(node a,node b)
{
if(a.x>b.x || (a.x==b.x && a.l>b.l))return a;
return b;
}
node min(node a,node b)
{
if(a.x>b.x || (a.x==b.x && a.l>b.l))return b;
return a;
}
void write(ll x){if(x>9) write(x/10);P(x%10+'0');}
int n,a[N],ans[N],v[N];
int main()
{
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
read(n);up[0].l=2;down[0].l=5;
for(int i=1;i<=n;i++)
{
read(a[i]);
t=up[i-1];
if(t.l+1>2)t.x++,t.l=1;else t.l++;
tt.x=a[i];tt.l=2;
if(a[i])up[i]=min(t,tt);else up[i]=t;
t=down[i-1];
if(t.l+1>5)t.x++,t.l=1;else t.l++;
tt.l=1;
if(a[i])down[i]=max(t,tt);else down[i]=t;
}
if(a[1]>1)
{
printf("-1");
return 0;
}
if(up[n].l==1)up[n].x--;
for(int i=1;i<=n;i++)
{
if(a[i])
{
if(a[i]<down[i].x || a[i]>up[i].x)
{
printf("-1");
return 0;
}
ans[i]=a[i];
}
if(up[i].x<down[i].x)
{
printf("-1");
return 0;
}
}
v[ans[n]=up[n].x]++;
for(int i=n-1;i;i--)
{
if(!a[i])
{
ans[i]=min(ans[i+1],up[i].x);
if(v[ans[i]]==5)ans[i]--;
}
v[ans[i]]++;
}
printf("%d\n",ans[n]);
for(int i=1;i<=n;i++)
write(ans[i]),P('\n');
return 0;
}