Codeforces Round #631 (Div. 2)
地址:http://codeforces.com/contest/1330
题意:题意不太好理解。简单来讲就是,给出一组数,能从1最多数到几,不够的用数来填,最多填x次。
解析:从1往前数,没有就填,填x次。填完后,记得再往后数,数到map[i]==0为止。
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1e2+10; int a[maxn]; int main() { int t; cin>>t; while(t--) { int n,x; cin>>n>>x; map<int,int>mm; for(int i=1;i<=n;i++) { int k; cin>>k; mm[k]++; } int cnt=1,ans=0; int k; for(int i=1;;i++) { if(ans==x) break; if(mm[i]==0) { ans++; k=i; } } int mid=k; for(int i=k+1;i<=1000;i++) { if(mm[i]>0) { mid=i; } else break; } cout<<mid<<endl; } }
题意:给出一组数,要求分成两部分,一部分假设有m个数,保证这部分的数字从1-m均出现而且仅出现一次。输出所有可能。
解析:从前往后扫一遍,符合条件的用va[]标记上,再从后往前扫一遍,符合条件的vb[]标记。如果va[i]==vb[i+1]==1(相邻而且均被标记),那么就输出这个可能。判定时可以用set来做,set可以去重,所以只要保证长度为m,而且set的最小是1,最大是m,那么就是一个符合条件的部分。
#include<iostream> #include<cstdio> #include<cstring> #include<set> #include<map> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2e5+10; int a[maxn]; int va[maxn],vb[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; va[i]=0; vb[i]=0; } set<int>s; set<int>::iterator it; int maxx=-1; for(int i=1;i<=n;i++) { s.insert(a[i]); if(a[i]>maxx) maxx=a[i]; if(s.size()==i) { int ok1=0,ok2=0; if(maxx==i) ok1=1; it=s.find(1); if(it!=s.end()) ok2=1; if(ok1&&ok2) { va[i]=1; } } } s.clear(); maxx=-1; for(int i=n;i>=1;i--) { s.insert(a[i]); if(a[i]>maxx) maxx=a[i]; if(s.size()==(n-i+1)) { int ok1=0,ok2=0; if(maxx==n-i+1) ok1=1; it=s.find(1); if(it!=s.end()) ok2=1; if(ok1&&ok2) vb[i]=1; } } int cnt=0; for(int i=1;i<=n;i++) { if(va[i]==1&&vb[i+1]==1) { cnt++; } } cout<<cnt<<endl; if(cnt==0) continue; for(int i=1;i<=n;i++) { if(va[i]==1&&vb[i+1]==1) { cout<<i<<" "<<n-i<<endl; } } } }