赞
踩
A. Cover in Water
类似于mc中的填水规则,模拟即可。如果有长度大于2的水槽就可以无限取水,答案为2;否则计算所有水槽总长度。
- #include<bits/stdc++.h>
- using namespace std;
- int main()
- {
- int t,n;
- vector<int>v;
- string s;
- cin>>t;
- while(t--)
- {
- v.clear();
- cin>>n;
- cin>>s;
- s=s+'#';
- for(int i=0;i<n;i++)
- {
- if(s[i]=='#') continue;
- for(int j=i;j<=n;j++)
- {
- if(s[j]=='#')
- {
- v.push_back(j-i);
- i=j;
- break;
- }
- }
- }
- if(!v.size())
- {
- cout<<"0\n";
- continue;
- }
- int flag=0;
- for(int i=0;i<v.size();i++)
- if(v[i]>2)
- {
- flag=1;
- break;
- }
- if(flag) cout<<"2\n";
- else
- {
- int sum=0;
- for(int i=0;i<v.size();i++) sum+=v[i];
- cout<<sum<<'\n';
- }
- }
- }

B. Laura and Operations
猜结论,看abc中奇数多还是偶数多,多的就是1。
- #include<bits/stdc++.h>
- using namespace std;
- int main()
- {
- int t,a[4],st[4];
- cin>>t;
- while(t--)
- {
- memset(st,0,sizeof(st));
- int maxx=0;
- for(int i=1;i<=3;i++) cin>>a[i],a[i]%=2;
- if(a[1]==a[2]&&a[2]==a[3]) cout<<"1 1 1\n";
- else
- {
- int x=0,y=0;
- for(int i=1;i<=3;i++)
- if(a[i]==1) x++;
- else y++;
- if(x<y)
- for(int i=1;i<=3;i++)
- if(a[i]) cout<<"1 ";
- else cout<<"0 ";
- else
- for(int i=1;i<=3;i++)
- if(a[i]==0) cout<<"1 ";
- else cout<<"0 ";
- cout<<'\n';
- }
- }
- }

C. Anji's Binary Tree
模拟树形dp即可,根据叶子结点和父结点的关系判断是否对dp值+1,注意只有叶子节点才能为U,不然会走死循环。
- #include<bits/stdc++.h>
- using namespace std;
- int t,n,l[300010],r[300010],dp[300010],dpl[300010],dpr[300010];
- string s;
- void dfs(int u)
- {
- if(l[u])
- {
- dfs(l[u]);
- if(s[u]=='L') dpl[u]=dp[l[u]];
- else dpl[u]=dp[l[u]]+1;
- }
- if(r[u])
- {
- dfs(r[u]);
- if(s[u]=='R') dpr[u]=dp[r[u]];
- else dpr[u]=dp[r[u]]+1;
- }
- if(l[u]&&!r[u]) dp[u]=dpl[u];
- else if(!l[u]&&r[u]) dp[u]=dpr[u];
- else if(l[u]&&r[u]) dp[u]=min(dpl[u],dpr[u]);
- else dp[u]=0;
- }
- void solve()
- {
- cin>>n;
- for(int i=1;i<=n;i++) dp[i]=0,dpl[i]=0,dpr[i]=0;
- cin>>s;
- s='?'+s;
- for(int i=1;i<=n;i++) cin>>l[i]>>r[i];
- dfs(1);
- cout<<dp[1]<<'\n';
- }
- int main()
- {
- cin>>t;
- while(t--) solve();
- }

D. Small GCD
注意到只需要对更小的两个数求gcd,考虑将数组排序后固定最大值,那么从左向右做扫描依次对每个最大值做计算,然后从最大值的左侧寻找两个较小的值求gcd总和。问题就变为如何求区间中任意两数的gcd总和,和hdu4676类似,答案为,d为所有数的因子。
本题只需要求n-1个区间的答案,且区间的左端点均为1,那么就比较好维护了。每次加入新的数时,如果某个因子d的次数增加1,那么由组合数可知,答案就会增加,然后令
加1即可,时间复杂度为
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N=100010;
- ll res=0,sum=0;
- int t,n,primes[N],Cnt;
- ll phi[N],a[N],cnt[N];
- bool st[N];
- void init(int n)
- {
- phi[1]=1;
- for(int i=2;i<=n;i++)
- {
- if(!st[i])
- {
- primes[Cnt++]=i;
- phi[i]=i-1;
- }
- for(int j=0;i*primes[j]<=n;j++)
- {
- st[i*primes[j]]=true;
- if(i%primes[j]==0)
- {
- phi[i*primes[j]]=phi[i]*primes[j];
- break;
- }
- phi[i*primes[j]]=phi[i]*(primes[j]-1);
- }
- }
- }
- void add(int x)
- {
- for(int i=1;i<=x/i;i++)
- {
- if(x%i==0)
- {
- sum+=phi[i]*cnt[i],cnt[i]++;
- if(i!=x/i) sum+=phi[x/i]*cnt[x/i],cnt[x/i]++;
- }
- }
- }
- void solve()
- {
- memset(cnt,0,sizeof(cnt));
- cin>>n;
- for(int i=1;i<=n;i++) cin>>a[i];
- sort(a+1,a+n+1);
- sum=0,res=0;
- for(int i=1;i<n;i++) add(a[i]),res+=sum;
- cout<<res<<'\n';
- }
- int main()
- {
- cin>>t;
- init(100000);
- while(t--) solve();
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。