http://codeforces.com/gym/101889ios
Ac++
B - Buggly ICPCide
在寫一串字符串時,每當寫到元音字母就會時總體字符串翻轉一次,問獲得目標字符串有幾種書寫方式。ui
分狀況討論,只有輔音時只有一種,每次翻轉必有一個元音字母到首位,多個元音存在時,只與最開始要書寫的元音字母有關。spa
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char s[100005]; int vis[100005],ans=0; bool match(char ch){ if(ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') return true; return false; } int main(){ scanf("%s",s); int pos=0,flag=false; memset(vis,0,sizeof(vis)); for(int i=0;s[i];i++){ if(i==0 && match(s[i])) flag=true; if(match(s[i])){ vis[ans]=pos; pos=0; ans++; } else pos++; } vis[ans]=pos; if(ans==0) printf("1\n"); else if(!flag) printf("0\n"); else{ int k=ans/2+1; if(ans&1) printf("%d\n",vis[k]+1); else printf("%d\n",vis[k-1]+1); } return 0; }
C - Complete Naebbirac's sequence3d
給你一個k和一個n,而後給你n個數,如今要你只操做一次,加一個數或者減一個數,使得全部的數次出現的次數相等,若不能獲得,輸出*;c++11
全部的數字不會超過K,若輸出+號或者-號,說明只能出現一次,首先得出每一個數字出現的平均次數t=(n+1)/k,所以vector標記下,討論下便可,看題目,k>=3,code
上式成立,若K等於1,則答案不惟一。blog
#include <bits/stdc++.h> #pragma GCC diagnostic error "-std=c++11" using namespace std; int n,k,a[1006]; vector<int>add,sub,mid; int main(){ scanf("%d%d",&k,&n); for(int i=0,x;i<n;i++){ scanf("%d",&x); a[x]++; } int t=(n+1)/k; for(int i=1;i<=k;i++){ if(a[i]==t) continue; else if(a[i]==t+1) add.push_back(i); else if(a[i]==t-1) sub.push_back(i); else mid.push_back(i); } if(add.size()==1 && !sub.size() && !mid.size()) printf("-%d\n",add[0]); else if(!add.size() && sub.size()==1 && !mid.size()) printf("+%d\n",sub[0]); else if(!mid.size() && sub.size()==1 && add.size()==1) printf("-%d +%d\n",add[0],sub[0]); else printf("*\n"); return 0; }
D排序
E - Enigma
給你一個文本s由?和數字字符組成,?能夠被任意數字字符代替,問得出最小的數字能夠整除N。
記憶話搜索
#include <bits/stdc++.h> #pragma GCC diagnostic error "-std=c++11" using namespace std; int vis[1003][1003]; bool pos[1003][1003]; string ans,s; int n,m,len; bool dfs(int idx,int res){ if(idx>=len) return res==0; if(vis[idx][res]) return pos[idx][res]; vis[idx][res]=1; if(s[idx]=='?'){ for(int i=!idx;i<=9;i++){ pos[idx][res]=max(pos[idx][res],dfs(idx+1,(res*10+i)%n)); if(pos[idx][res]) return true; } } else pos[idx][res]=max(pos[idx][res],dfs(idx+1,(res*10+(s[idx]-'0'))%n)); return pos[idx][res]; } void solve(int idx,int res){ if(idx==len) return ; if(s[idx]=='?'){ for(int i=!idx;i<=9;i++){ if(dfs(idx+1,(res*10+i)%n)){ ans+=(char)(i+'0'); solve(idx+1,(res*10+i)%n); return ; } } } else{ ans+=s[idx]; solve(idx+1,(res*10+(s[idx]-'0'))%n); return ; } } int main(){ cin>>s>>n; len=s.size(); if(dfs(0,0)){ solve(0,0); cout<<ans<<endl; } else printf("*\n"); return 0; }
F - Fundraising
有n我的,每一個人有本身的美麗值,財富值,和貢獻度,如今挑選若干人,而且,只有兩我的的財富值和美麗值徹底相等或者一我的的財富值和美麗值徹底大於另外一我的纔不會起衝突,問在不起衝突的條件下能夠獲得的最大貢獻值是多少。
離散化線段樹。
將每一個人的財富值即縱座標離散,而後排序,每次查詢即在二維座標系中找斜率大於0的直線。注意有重點。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=100006; int n,m; vector<int>v; struct Node{ int x,y; ll v; bool operator<(const Node &b) const{ return b.x==x?b.y>y:b.x>x; } }a[maxn],e[maxn]; ll vis[100006][2]; struct tree { ll val; int left,right; }tree[maxn<<2]; void PushUp(int root){ tree[root].val=max(tree[root<<1].val,tree[root<<1|1].val); } void build(int l,int r,int root) { tree[root].val=0; tree[root].left=l; tree[root].right=r; if(l==r) return ; int mid=l+r>>1; build(l,mid,root<<1); build(mid+1,r,root<<1|1); PushUp(root); } void update(int root,int pos,ll val) { if(tree[root].left==tree[root].right){ tree[root].val=max(val,tree[root].val); return ; } int mid=tree[root].left+tree[root].right>>1; if(pos<=mid) update(root<<1,pos,val); else update(root<<1|1,pos,val); PushUp(root); } ll query(int root,int l,int r) { if(l>r) return 0; if(l<=tree[root].left && r>=tree[root].right){ return tree[root].val; } int mid=tree[root].left+tree[root].right>>1; ll ans=0; if(l<=mid) ans=max(ans,query(root<<1,l,r)); if(r>mid) ans=max(ans,query(root<<1|1,l,r)); return ans; } int get_id( int x ){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } int main(){ scanf("%d",&n); for( int i=0; i<n ;i++){ scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].v); v.push_back(a[i].y) ; } sort(v.begin(),v.end()) ; v.erase(unique(v.begin(),v.end()),v.end()); sort(a,a+n); m=v.size(); build(1,m,1); ll inf=0; int tot=-1,l=0; for(int i=0;i<n;i++){ if(i && a[i].x==a[i-1].x && a[i].y==a[i-1].y){ e[tot].v+=a[i].v; } else{ tot++; e[tot].x=a[i].x; e[tot].y=get_id(a[i].y); e[tot].v=a[i].v; } } e[++tot].x=1000000007; vis[0][1]=e[0].v; for(int i=0;i<tot;i++){ ll ans=query(1,1,e[i].y-1); vis[i][0]=ans+e[i].v; if(e[i].x!=e[i+1].x){ for(int j=l;j<=i;j++) update(1,e[j].y,vis[j][0]); l=i+1; } } printf("%lld\n",query(1,1,m)); return 0; }
G
H - Hard choice
已知航班提供的三種盒飯的數量,而後給出每種盒飯有多少乘客想要,問有多少人吃不上飯。
#include <bits/stdc++.h> using namespace std; int a[4]; int main(){ int ans=0; for(int i=0;i<3;i++) scanf("%d",&a[i]); for(int i=0,x;i<3;i++){ scanf("%d",&x); ans+=max(0,x-a[i]); } printf("%d\n",ans); return 0; }
I
J - Jumping Frog
一個字符串只有RP組成,R表明岩石,P表明池塘,frog只能從岩石開始起跳,而且不能中途調到池塘裏,每次能夠跳K步,只要最後能夠跳回起始點,則此K可取
問K有多少種取法。
gcd的應用
#include <bits/stdc++.h> #pragma GCC diagnostic error "-std=c++11" using namespace std; char s[100005]; bool vis[100005]; int len; int main(){ scanf("%s",&s); len=strlen(s); for(int i=1;i<len;i++){ if(len%i) continue; for(int j=0;j<i;j++){ vis[i]=1; for(int k=0;k<=len/i;k++){ if(s[k*i+j]=='P'){ vis[i]=0; break; } } if(vis[i]) break; } } int ans=0; for(int i=1;i<len;i++) if(vis[__gcd(i,len)]) ans++; printf("%d\n",ans); return 0; }
K