地址: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; } }