环鸽的CHONG(dfs分治)
原创
©著作权归作者所有:来自51CTO博客作者wx63316144dde40的原创作品,请联系作者获取转载授权,否则将追究法律责任
地址:https://ac.nowcoder.com/acm/problem/206047
解析:
对于整个的区间[1,n],如果有一个数只出现了一次,下标为x,那么有:[1,x,n],对于里面的任意区间,只要涉及到x,它直接就是好序列。
所以就把区间分成两部分:[1,x-1][x+1,n]。
接下来,对于当前要看的区间[lx,rx],如果里面有一个数,它的之前出现位置在lx之前,之后的出现位置在rx之后,那么这个序列也是个好序列。
再次分割。
对于一个数的之前与之后的出现位置,有代码:
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(!mp[a[i]])
l[i]=0;
else
l[i]=mp[a[i]];
mp[a[i]]=i;
if(a[i]==a[i-1])
{
ok=0;
}
}
mp.clear();
for(int i=n;i>=1;i--)
{
if(!mp[a[i]])
r[i]=n+1;
else
r[i]=mp[a[i]];
mp[a[i]]=i;
}
真的很好用,建议好好看好好学
接下来是AC代码:
#include<bits/stdc++.h>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
map<int,int>mp;
int l[maxn],r[maxn];
int a[maxn];
bool dfs(int lx,int rx)
{
if(lx>=rx)
return 1;
int md=lx;
while(md<=rx)
{
if(l[md]<lx&&r[md]>rx)
return dfs(lx,md-1)&&dfs(md+1,rx);
md++;
}
return 0;
}
int main()
{
int n;
cin>>n;
int ok=1;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(!mp[a[i]])
l[i]=0;
else
l[i]=mp[a[i]];
mp[a[i]]=i;
if(a[i]==a[i-1])
{
ok=0;
}
}
mp.clear();
for(int i=n;i>=1;i--)
{
if(!mp[a[i]])
r[i]=n+1;
else
r[i]=mp[a[i]];
mp[a[i]]=i;
}
if(!ok)
cout<<"fuchong"<<endl;
else
{
ok=dfs(1,n);
if(!ok)
cout<<"fuchong"<<endl;
else
cout<<"chong"<<endl;
}
}