「Diligent-OI R3 B」天际线
题目分析
首先如果
不妨记录
然后考虑字典序的贪心。你发现按道理来说在
然后
有一个 corner case 就是
时间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
constexpr int N=1e5+2;
int T,n,a[N],b[N],c[N],pre[N],ans[N],vis[N],lsta,fstb;
string sa,sb,sc;
void task(){
memset(ans,0,sizeof(ans)),
memset(vis,0,sizeof(vis));
cin>>n>>sa>>sb>>sc;
sa=" "+sa,sb=" "+sb,sc=" "+sc;
for(int i=1;i<=n;i++)
a[i]=(sa[i]-'0'),b[i]=(sb[i]-'0'),c[i]=(sc[i]-'0');
lsta=0,fstb=n+1;
for(int i=1,prenc=0;i<=n;i++){
if(c[i]&&(a[i]||b[i]))
return println("-1");
if(a[i])
lsta=i;
if(b[i]&&fstb>n)
fstb=i;
if(!c[i])
prenc=i;
pre[i]=prenc;
}
if(lsta>fstb||c[n])
return println("-1");
for(int i=1;i<fstb;i++)
if(c[i]){
if(!pre[i])
return println("-1");
ans[pre[i]]=i;
}
for(int i=1;i<fstb;i++)
if(ans[i])
vis[ans[i]]=1;
for(int i=1,j=1;i<fstb;i++){
while(vis[j])
j++;
if(!ans[i])
ans[i]=j,vis[j]=1;
}
for(int i=fstb,j1=1,j2=n;i<=n;i++){
while(vis[j1])
j1++;
while(vis[j2])
j2--;
if(b[i])
ans[i]=j2,vis[j2]=1;
else
ans[i]=j1,vis[j1]=1;
}
for(int i=1;i<=n;i++)
print("{} ",ans[i]);
return println("");
}
string program(){
cin.tie(nullptr)->ios::sync_with_stdio(0);
for(cin>>T;T;T--)
task();
return"H17";
}
string H17=program();
int main(){
return 0;
}