当前位置:   article > 正文

The 2022 ICPC Asia Hangzhou Regional Programming Contest

the 2022 icpc asia hangzhou regional programming contest

比赛连接:Dashboard - The 2022 ICPC Asia Hangzhou Regional Programming Contest - Codeforces

A. Modulo Ruins the Legend

题目大意:

给你一个长度为n的数组,确定s,d的值,对于数组第k个元素ak加上s+kd,k∈[1,n],使得加上后数组的和模m后值最小。

0<=s<m;0<=d<m;如果多解输出任意一个满足条件的即可。

n,m (1≤n≤10^5, 1≤m≤10^9).

思路:

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=9901;
  33. const int N=25;
  34. int gcd(int a,int b)
  35. {
  36. if(!b) return a;
  37. return gcd(b,a%b);
  38. }
  39. int exgcd(int a,int b,int &x,int &y)
  40. {
  41. if(!b){
  42. x=1,y=0;
  43. return a;
  44. }
  45. int d=exgcd(b,a%b,y,x);
  46. y-=a/b*x;
  47. return d;
  48. }
  49. void solve()
  50. {
  51. int n,m,x,y,sum=0;
  52. cin>>n>>m;
  53. rep(i,0,n){
  54. cin>>x;
  55. sum=(sum+x)%m;
  56. }
  57. int s,d;
  58. int g0=exgcd(n%m,1ll*n*(n+1)/2%m,s,d);
  59. if(sum==0||g0==0){
  60. cout<<0<<endl<<0<<" "<<0<<endl;
  61. return;
  62. }
  63. int g=g0,ans,t=sum;
  64. while(1){
  65. g=gcd(g,m);
  66. if(t%g==0){
  67. ans=0;
  68. break;
  69. }
  70. if(g>t){
  71. ans=t;
  72. break;
  73. }
  74. t%=g;
  75. }
  76. int T=((ans-sum)%m+m)%m;
  77. g=exgcd(g0,m,x,y);
  78. x=1ll*x*T/g%m;
  79. x=(x+m)%m;
  80. s=1ll*s*x%m,d=1ll*d*x%m;
  81. s=(s+m)%m,d=(d+m)%m;
  82. cout<<ans<<endl;
  83. cout<<s<<" "<<d<<endl;
  84. }
  85. int main()
  86. {
  87. // #ifndef ONLINE_JUDGE
  88. // freopen("title.in","r",stdin);
  89. // freopen("title.out","w",stdout);
  90. // #endif
  91. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  92. int _=1;
  93. //cin>>_;
  94. while(_--){
  95. solve();
  96. }
  97. return 0;
  98. }

C. No Bug No Game

题目大意:

给定n个物品和限定k,要求最大化分数。物品的选择顺序可以任意。

第i物品一行pi代表个数,后面pi个wij代表容量(不一定递增),记录sum为∑pj (1≤j<i),对于第i个物品:

  • sum+pi≤k 得到w(i,pi)的分
  • sum≥k, 不能再加分了。
  • 否则得到w(i,k−sum)分。

1≤n≤3000, 0≤k≤3000

1≤pi≤10;1≤wi,j≤10^5

思路:

简单的背包问题变型,可以将sum看做是背包容量,在k之内做动态规划。区别就是如果sum+pi>k,就会有一个物品不选满(选到刚好达到k的容量并得到相应的价值)。

用f[i][j][z]表示从前i个物品当中选,总和刚好为j,且z=0表示所有物品选满,z=1表示有一个没有选满的物品。转移方程见代码。

最后在枚举更新答案的时候需要判断j==k的时候才可以更新f[i][j][1]这个情况。

代码: 

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=9901;
  33. const int N=3005;
  34. int f[N][N][2],w[15];
  35. void solve()
  36. {
  37. int n,k,p;
  38. cin>>n>>k;
  39. MEM(f,-0x3f);
  40. f[0][0][0]=0;
  41. rep(i,1,n+1){
  42. cin>>p;
  43. rep(j,1,p+1) cin>>w[j];
  44. per(j,k-1,-1){
  45. f[i][j][0]=f[i-1][j][0];
  46. f[i][j][1]=f[i-1][j][1];
  47. if(j+p<=k) f[i][j+p][0]=max(f[i][j+p][0],f[i-1][j][0]+w[p]),f[i][j+p][1]=max(f[i][j+p][1],f[i-1][j][1]+w[p]);
  48. rep(z,1,p) if(j+z<=k) f[i][j+z][1]=max(f[i][j+z][1],f[i-1][j][0]+w[z]);
  49. }
  50. }
  51. int ans=0;
  52. rep(i,1,n+1) rep(j,0,k+1){
  53. ans=max(ans,f[i][j][0]);
  54. if(j==k) ans=max(ans,f[i][j][1]);
  55. }
  56. cout<<ans;
  57. }
  58. int main()
  59. {
  60. #ifndef ONLINE_JUDGE
  61. freopen("title.in","r",stdin);
  62. freopen("title.out","w",stdout);
  63. #endif
  64. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  65. int _=1;
  66. //cin>>_;
  67. while(_--){
  68. solve();
  69. }
  70. return 0;
  71. }

D. Money Game

题目大意:

n个人玩游戏,第i个人初始值为ai;每一轮会进行:从前往后,前一个人把他的值一半给后一个人,最后一个会给第一个。

问经过2022^1204轮之后,输出每个人的值,误差在10^-6之内。

2≤n≤10^5

1≤ai≤10^6

思路:

打表可以看出经过很多轮次后,最后满足a1=2*a2=...=2*an,而且整个序列的和不会因为操作而改变。数值的和记为s,当次数趋于无穷时,第一个数为2s/(n+1),后面都是s/(n+1)。

代码: 

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=9901;
  33. const int N=25;
  34. void solve()
  35. {
  36. int n;
  37. db s=0;
  38. cin>>n;
  39. rep(i,0,n){
  40. db x;
  41. cin>>x;
  42. s+=x;
  43. }
  44. s/=(n+1);
  45. rep(i,0,n) if(i) printf("%.7lf ",s); else printf("%.7lf ",2*s);
  46. }
  47. int main()
  48. {
  49. // #ifndef ONLINE_JUDGE
  50. // freopen("title.in","r",stdin);
  51. // freopen("title.out","w",stdout);
  52. // #endif
  53. //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  54. int _=1;
  55. //cin>>_;
  56. while(_--){
  57. solve();
  58. }
  59. return 0;
  60. }

E. Oscar is All You Need

题目大意:

T组测试,每组给定一个n,和1-n的排列,可以最多操作2*n+1次,每次操作将数组分为非空的三个部分,交换第一个和第三个部分。问字典序最小序列。输出操作次数和方案。(不要求操作次数最小)

1≤T≤120

3≤n≤1000

思路:

 

 

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=9901;
  33. const int N=1010;
  34. int n,a[N],b[N],sz;
  35. pii p[2*N+5];
  36. int got(int x)
  37. {
  38. rep(i,1,n+1) if(a[i]==x) return i;
  39. }
  40. void op(int l,int r)
  41. {
  42. p[++sz]={l-1,n-r};
  43. int cnt=0;
  44. rep(i,r+1,n+1) b[++cnt]=a[i];
  45. rep(i,l,r+1) b[++cnt]=a[i];
  46. rep(i,1,l) b[++cnt]=a[i];
  47. rep(i,1,n+1) a[i]=b[i];
  48. }
  49. void solve()
  50. {
  51. cin>>n;
  52. rep(i,1,n+1) cin>>a[i];
  53. if(n==3){
  54. if(a[1]>a[3]) cout<<1<<endl<<1<<" "<<1<<endl;
  55. else cout<<0<<endl;
  56. return;
  57. }
  58. sz=0;
  59. int k=got(1);
  60. if(k!=1){
  61. if(k==2) op(3,3),op(n-1,n-1);
  62. else op(k-1,k-1);
  63. }
  64. rep(i,2,n-1){
  65. k=got(i);
  66. if(k==i) continue;
  67. if(k==i+1) op(i,i+1),op(n-i+1,n-i+1);
  68. else op(i,i),op(k-i,n-i+1);
  69. }
  70. if(a[n-1]!=n-1) op(n-2,n-1),op(2,2),op(2,n-1),op(n-1,n-1),op(2,3);
  71. cout<<sz<<endl;
  72. rep(i,1,sz+1) cout<<p[i].fi<<" "<<p[i].se<<endl;
  73. }
  74. int main()
  75. {
  76. // #ifndef ONLINE_JUDGE
  77. // freopen("title.in","r",stdin);
  78. // freopen("title.out","w",stdout);
  79. // #endif
  80. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  81. int _=1;
  82. cin>>_;
  83. while(_--){
  84. solve();
  85. }
  86. return 0;
  87. }

F. Da Mi Lao Shi Ai Kan De

题目大意:

有n各组,每组给一些字符串,从组中选择含有字串"bie"的加入到一组中(如果存在了不加了),如果可以添加就输出这个字符串,否则输出“Time to play Genshin Impact, Teacher Rice!”

思路:

水题,用string和set模拟即可。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=9901;
  33. const int N=25;
  34. set<string>st;
  35. void solve()
  36. {
  37. int n;
  38. bool f=0;
  39. cin>>n;
  40. while(n--){
  41. string s;
  42. cin>>s;
  43. if(s.find("bie")!=-1&&st.find(s)==st.end()){
  44. cout<<s<<endl;
  45. st.insert(s),f=1;
  46. }
  47. }
  48. if(!f) cout<<"Time to play Genshin Impact, Teacher Rice!"<<endl;
  49. }
  50. int main()
  51. {
  52. // #ifndef ONLINE_JUDGE
  53. // freopen("title.in","r",stdin);
  54. // freopen("title.out","w",stdout);
  55. // #endif
  56. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  57. int _=1;
  58. cin>>_;
  59. while(_--){
  60. solve();
  61. }
  62. return 0;
  63. }

K. Master of Both

题目大意:

给定n个字符串,q此询问,每一次询问都定义一个字母字典序大小规则,在这种大小规则下求n个字符串逆序对的个数。

1≤n≤5×10^5, 1≤q≤5×10^4

思路:

在比较两个字符串的时候,只需要比较第一个不相同字母的大小就可以了。建立trie树,在建树的过程中维护cnt[p]的值,表示以p为前缀的字符串个数。再用inv[i][j]记录序列中(j,i)的对数个数。

注意有一种特殊情况需要单独算:当一个字符串插入完后,要加上其所有的子节点。因为它可能是前面字符串的一个前缀,这种情况它一定会和这些字符串构成逆序对。

最后计算答案就是两重循环,每次加上预处理出来的inv[i][j] (j>i)即可。

代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <cmath>
  7. #include <stack>
  8. #include <queue>
  9. #include <vector>
  10. #include <map>
  11. #include <set>
  12. #include<bitset>
  13. #include<list>
  14. #include <algorithm>
  15. #define pii pair<int,int>
  16. #define pll pair<LL,LL>
  17. #define pil pair<int,LL>
  18. #define pli pair<LL,int>
  19. #define pdd pair<db,db>
  20. #define se second
  21. #define fi first
  22. #define endl '\n'
  23. #define rep(i,a,b) for (register int i=a;i<b;++i)
  24. #define per(i,a,b) for (register int i=a;i>b;--i)
  25. #define MEM(a,x) memset(a,x,sizeof(a))
  26. #define M(x) ((x)%MOD)
  27. #define db double
  28. #define eps 1e-9
  29. typedef long long LL;
  30. typedef unsigned long long ULL;
  31. using namespace std;
  32. const int MOD=1e9+7;
  33. const int N=1e6+10;
  34. int tr[N][26],idx=1;
  35. LL tot,cnt[N],inv[26][26];
  36. string s;
  37. void ins()
  38. {
  39. int p=1;
  40. ++cnt[p];
  41. rep(i,0,s.size()){
  42. int j=s[i]-'a';
  43. rep(k,0,26) if(j!=k) inv[j][k]+=cnt[tr[p][k]];
  44. if(tr[p][j]==0) tr[p][j]=++idx;
  45. p=tr[p][j],++cnt[p];
  46. }
  47. rep(i,0,26) tot+=cnt[tr[p][i]];
  48. }
  49. void solve()
  50. {
  51. int n,q;
  52. cin>>n>>q;
  53. while(n--){
  54. cin>>s;
  55. ins();
  56. }
  57. while(q--){
  58. LL ans=0;
  59. cin>>s;
  60. rep(i,0,s.size()) rep(j,i+1,s.size()) ans+=inv[s[i]-'a'][s[j]-'a'];
  61. cout<<ans+tot<<endl;
  62. }
  63. }
  64. int main()
  65. {
  66. #ifndef ONLINE_JUDGE
  67. freopen("title.in","r",stdin);
  68. freopen("title.out","w",stdout);
  69. #endif
  70. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  71. int _=1;
  72. //cin>>_;
  73. while(_--){
  74. solve();
  75. }
  76. return 0;
  77. }

开坑开坑~~~

由于期末考试压力,其他题目待补题qwq,后面会持续更新~

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

闽ICP备14008679号