当前位置:   article > 正文

Codeforces Round 494 (Div. 3)

Codeforces Round 494 (Div. 3)

目录

A. Polycarp's Pockets

B. Binary String Constructing

C. Intense Heat

D. Coins and Queries

E. Tree Constructing

F. Abbreviation


A. Polycarp's Pockets

记录数量可以直接开一个桶即可然后求最大值

  1. void solve(){
  2. cin>>n;
  3. vector<int> ton(105);
  4. int ans=0;
  5. while(n--){
  6. int x; cin>>x;
  7. ton[x]++;
  8. ans=max(ans,ton[x]);
  9. }
  10. cout<<ans<<endl;
  11. return ;
  12. }

B. Binary String Constructing

先按照01010这样的方式把题目要求构造出来然后往中间插入01即可这样答案不会变化

  1. void solve(){
  2. int a,b,n; cin>>a>>b>>n;
  3. vector<int> s(n+5);
  4. if(b>a) s[1]=1,b--;
  5. else a--;
  6. for(int i=2;i<=n+1;i++){
  7. s[i]=s[i-1]^1;
  8. if(s[i]) b--;
  9. else a--;
  10. }
  11. for(int i=1;i<=n+1;i++){
  12. cout<<s[i];
  13. if(s[i]) while(b) cout<<1,b--;
  14. else while(a) cout<<0,a--;
  15. }
  16. return ;
  17. }

C. Intense Heat

暴力前缀和统计最大平均值即可

  1. void solve(){
  2. cin>>n>>m;
  3. vector<int> a(n+5);
  4. for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
  5. double res=0;
  6. for(int i=1;i<=n;i++)
  7. for(int j=i+m-1;j<=n;j++)
  8. res=max(res,1.0*(a[j]-a[i-1])/(j-i+1));
  9. cout<<LF(7)<<res<<endl;
  10. return ;
  11. }

D. Coins and Queries

类似二进制从大到小取满整个数即可

  1. void solve(){
  2. cin>>n>>m;
  3. vector<int> cnt(33);
  4. for(int i=1;i<=n;i++){
  5. int x; cin>>x;
  6. cnt[log2(x)]++;
  7. }
  8. while(m--){
  9. int x; cin>>x;
  10. int ans=0;
  11. for(int i=31;i>=0;i--){
  12. int t=min(x/(1<<i),cnt[i]);
  13. ans+=t;
  14. x-=(1<<i)*t;
  15. }
  16. if(x) ans=-1;
  17. cout<<ans<<endl;
  18. }
  19. return ;
  20. }

E. Tree Constructing

构造一棵树我们可以发现如果是又满足的一定是一条直径是d的我们不妨直接把直径构造出来,然后在其中的点加入限制条件之后直接构造,注意题目的意思是构造出来的树直径就是d所以按照题目要求然后对其中的点扩充即可

  1. vector<PII> ans;
  2. void dfs(int u,int now,int d){
  3. if(now==d) return ;
  4. for(int i=1;i<=k-1-(now==0)&&cnt<n;i++){//初始进来的时候是中间节点表示以及少了两个度了
  5. cnt++;
  6. ans.push_back({u,cnt});
  7. dfs(cnt,now+1,d);
  8. }
  9. }
  10. void solve()
  11. {
  12. cin>>n>>d>>k;
  13. if(n-1<d){// 表示建立不了这枚长
  14. cout<<"NO"<<endl;
  15. return ;
  16. }// n个点建立 n-1 为最长的直径
  17. if(k==1){// 特殊情况特殊判断
  18. if(n==2&&d==1){
  19. cout<<"YES"<<endl;
  20. cout<<1<<' '<<2<<endl;
  21. }
  22. else cout<<"NO"<<endl;
  23. return ;
  24. }
  25. for(int i=1;i<=d;i++){
  26. ans.push_back({i,i+1});
  27. }
  28. cnt=d+1;
  29. for(int i=1;i<=d+1;i++)
  30. dfs(i,0,min(i-1,d-i+1));// 表示当前的还可以构造的深度
  31. if(cnt<n){
  32. cout<<"NO"<<endl;
  33. }
  34. else{
  35. cout<<"YES"<<endl;
  36. for(auto&[a,b]:ans) cout<<a<<' '<<b<<endl;
  37. }
  38. return ;
  39. }

F. Abbreviation

整个题目注意题目意思,以及数据范围(300-500)一般都是n^3时间复杂度来解决,接着我们要的是找到一段相同的然后把整个里面相同的进行缩写处理,不妨先把整个用vector<string> 存储起来,接着我们要考虑的就是相同的长度是多少,接着考虑从什么位置开始,我们 由此可以设置状态

dp[i][j]表示 状态表示 以第i个结尾的 和以第j个结尾的最长相同后缀长度是多少这样就满足了什么位置开始长度是多少,接着枚举位置和长度来求解即可

  1. vector<string> a;
  2. void solve(){
  3. a.push_back(" ");
  4. cin>>n;
  5. int tol=0;
  6. for(int i=1;i<=n;i++){
  7. string s; cin>>s;
  8. a.push_back(s);
  9. tol+=s.size();
  10. }
  11. tol+=n-1;// 求出总空间需求
  12. int ans=tol;
  13. // 状态表示 以第i个结尾的 和以第j个结尾的最长相同后缀长度是多少
  14. for(int i=1;i<=n;i++)
  15. for(int j=i+1;j<=n;j++)
  16. if(a[i]==a[j])
  17. dp[i][j]=dp[i-1][j-1]+1;
  18. for(int i=n;i>=1;i--){// 以i为结尾
  19. int sum=0;// 长度
  20. for(int d=1;i-d>=0;d++){
  21. sum+=a[i-d+1].size();
  22. int cnt=0;
  23. for(int j=i-d;j>=1;)// j开始
  24. if(dp[j][i]>=d){
  25. j-=d;
  26. cnt++;
  27. }
  28. else j--;
  29. if(cnt){
  30. cnt++;
  31. int now=tol-sum*cnt+cnt;
  32. //对于整个缩写减少的是字母占据的位置,同时由于空格等于字母-1所以后面还要加一个1
  33. // cnt 个所以要加上cnt个1
  34. ans=min(ans,now);
  35. }
  36. }
  37. }
  38. cout<<ans<<endl;
  39. return ;
  40. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/136126?site
推荐阅读
相关标签
  

闽ICP备14008679号