不会写,所以我找到了一份十分优美的代码来学习:请自觉学习set的用法.因为set保证有序,而有序才能二分用lower_bound,返回set中大于某数的最小的值.
思路:确保每一个下雨的池塘之前都被吸干.比如1001不符合,0101符合.我们只要找到下雨的池塘,再找之前一次出现的这个池塘.理论上之前出现的这个池塘应该是要被吸干的,所以我们找与之前一次出现的池塘后面的最近的0,用它来吸干这个池塘
开一个rain数组,存每一天下雨的是哪一个池塘(0则代表没有池塘下雨)
开一个pre数组,初始化为0,存的是下雨的池塘的之前一次下雨的天数.比如 0 1 0 1:在第二天和第四天下雨.则pre[rain[2]]=0,pre[rain[4]]=1;
开一个ans,初始化为0,一旦rain[i]不为0,ans[i]=-1;当然还有ans[*it]=rain[i];(建议先看看代码)
#include<cstdio>
#include<cstring>
#include<string>
#include<string.h>
#include<set>
#include<algorithm>
#include<iostream>
#include<math.h>
#define maxn 1000008
#define ll long long
#define RPG(i,a,b) for(int i=(a);i<(b);i++)
using namespace std;
int rain[maxn],ans[maxn],pre[maxn];
int main()
{
int T,n,m;
scanf("%d",&T);
while(T--)
{
memset(pre,0,sizeof(pre));
memset(ans,0,sizeof(ans));
scanf("%d%d",&n,&m);
RPG(i,0,m)
scanf("%d",&rain[i]);
bool ok=true;
set<int> q;
set<int>::iterator it;
RPG(i,0,m)
{
if(!rain[i])
{
q.insert(i);
continue;
}
ans[i]=-1;
it=q.lower_bound(pre[rain[i]]);
if(it==q.end())
{
ok=false;
break;
}
ans[*it]=rain[i];
q.erase(*it);
pre[rain[i]]=i;
}
if(!ok)
puts("NO");
else
{
puts("YES");
bool f=true;
RPG(i,0,m)
if(ans[i]!=-1)
{
if(f){
f=false;
printf("%d",ans[i]);
}
else
printf(" %d",ans[i]);
}
puts("");
}
}
return 0;
}