• Codeforces Round #792 (Div. 1 + Div. 2)


    A. Digit Minimization

    题目链接:Problem - A - Codeforces

    样例输入: 

    1. 3
    2. 12
    3. 132
    4. 487456398

    样例输出:

    1. 2
    2. 1
    3. 3

    题意:给定一个长度小于10的字符串,Alice和Bob轮流操作,Alice每次可以选择将其中的两个字符交换位置,而Bob每次删除最后一个字符,最后剩下一个字符,问Alice最后能够得到的最小的字符是多少?

    分析:其实模拟不难发现,Alice可以把最后想得到的字符一开始通过交换换至前面,然后就可以最后剩下这个字符,根据贪心我们肯定是剩下原串中最小的那个字符,但是需要注意的一点是Alice是必须要进行操作的,如果一开始是两个字符,那么Alice只能最后剩下第二个字符。

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. using namespace std;
    9. const int N=1e5+10;
    10. int main()
    11. {
    12. int T;
    13. cin>>T;
    14. while(T--)
    15. {
    16. int x;
    17. scanf("%d",&x);
    18. if(x<100) printf("%d\n",x%10);
    19. else
    20. {
    21. int mi=9;
    22. while(x)
    23. {
    24. mi=min(mi,x%10);
    25. x/=10;
    26. }
    27. printf("%d\n",mi);
    28. }
    29. }
    30. return 0;
    31. }

    B. Z mod X = C

    题目链接:Problem - B - Codeforces

    样例输入: 

    1. 4
    2. 1 3 4
    3. 127 234 421
    4. 2 7 8
    5. 59 94 388

    样例输出:

    1. 12 11 4
    2. 1063 234 1484
    3. 25 23 8
    4. 2221 94 2609

    题意:给定一个a,b,c,让我们输出一组x,y,z满足xmody=a, ymodz=b, zmodx=c

    分析:直接设x=k1*y+a,y=k2*z+b,z=k3*x+c,然后联立方程令k3=0,k1=k2=1即可解得x=a+b+c,y=b+c,z=c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. using namespace std;
    9. const int N=1e5+10;
    10. int main()
    11. {
    12. int T;
    13. cin>>T;
    14. while(T--)
    15. {
    16. int a,b,c;
    17. scanf("%d%d%d",&a,&b,&c);
    18. printf("%d %d %d\n",a+b+c,b+c,c);
    19. }
    20. return 0;
    21. }

    C. Column Swapping

    题目链接:Problem - C - Codeforces

     样例输入:

    1. 5
    2. 2 3
    3. 1 2 3
    4. 1 1 1
    5. 2 2
    6. 4 1
    7. 2 3
    8. 2 2
    9. 2 1
    10. 1 1
    11. 2 3
    12. 6 2 1
    13. 5 4 3
    14. 2 1
    15. 1
    16. 2

    样例输出:

    1. 1 1
    2. -1
    3. 1 2
    4. 1 3
    5. 1 1

    题意:我们定义一行数是好的当且仅当我们对某对(i,j)(i可以等于j)进行一次交换后可以使得这行数是非递减的,现在给定一个矩阵,问我们能否正好交换两列使得每一行都是好的

    分析:这个题其实就是直接暴力找每一行需要交换的两个数的位置即可,如果出现两列需要交换的位置不一样就直接输出-1,否则输出这两列的编号,但是这道题细节比较多,下面给出两组容易出错的样例:

    1 3

    2 2 1

    1 3

    2 1 1

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<cstdio>
    5. #include<cmath>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. const int N=2e5+10;
    10. int a[N],n,m;
    11. int find(int i,int j)
    12. {
    13. return (i-1)*m+j;
    14. }
    15. int main()
    16. {
    17. int T;
    18. cin>>T;
    19. while(T--)
    20. {
    21. scanf("%d%d",&n,&m);
    22. int l=0,r=0;
    23. bool flag=true;
    24. for(int i=1;i<=n;i++)
    25. {
    26. int tl=0,tr=0;
    27. for(int j=1;j<=m;j++)
    28. {
    29. scanf("%d",&a[find(i,j)]);
    30. if(j==1) continue;
    31. if(a[find(i,j)]<a[find(i,j-1)])
    32. {
    33. if(!tl)
    34. tl=j-1;
    35. else if(!tr)
    36. tr=j;
    37. else
    38. flag=false;
    39. }
    40. }
    41. if(tl&&(!tr)) tr=tl+1;
    42. while(tl>1&&(a[find(i,tl)]==a[find(i,tl-1)])) tl--;
    43. while(tr<m&&(a[find(i,tr)]==a[find(i,tr+1)])) tr++;
    44. if(!tl) continue;
    45. if(!(l||r)) l=tl,r=tr;
    46. else
    47. {
    48. if((l!=tl)||(r!=tr)) flag=false;
    49. }
    50. }
    51. for(int i=1;i<=n;i++)
    52. {
    53. swap(a[find(i,l)],a[find(i,r)]);
    54. for(int j=1;j<m;j++)
    55. if(a[find(i,j)]>a[find(i,j+1)]) flag=false;
    56. }
    57. if(flag) printf("%d %d\n",l>0?l:1,r>0?r:1);
    58. else puts("-1");
    59. }
    60. return 0;
    61. }

    D. Traps

    题目链接:Problem - D - Codeforces

     样例输入:

    1. 5
    2. 4 4
    3. 8 7 1 4
    4. 4 1
    5. 5 10 11 5
    6. 7 5
    7. 8 2 5 15 11 2 8
    8. 6 3
    9. 1 2 3 4 5 6
    10. 1 1
    11. 7

    样例输出:

    1. 0
    2. 21
    3. 9
    4. 6
    5. 0

    题意:一开始有n个陷阱,每个陷阱都有一个损失值a[i],我们有k次跳过陷阱的机会,但是我们每跳过一次陷阱那么后面所有的陷阱的损失值就会+1,问我们在经过n个陷阱后的最小损失。

    分析:这道题我一开始写的是动态规划,设f[i][j]表示经过前i个陷阱使用了j次跳跃机会的最小损失,为了使得状态转移方程没有后效性,假如我们后面还有m个陷阱,还有k-j次跳跃机会,那么也就是说我们有m-(k-j)个陷阱都不能跳过,而且会因为本次的跳跃使得损失值+1,所以我们直接看作当前跳跃的代价即可,这样我们就能通过枚举第i个陷阱跳还是不跳来进行动态转移了。不过当时没细看数据范围,超时了,不过通过这个分析过程我找到了贪心的思路:

    就是说,假如我们没有使用跳跃那么我们的损失值就是\sum_{i=1}^{n}a[i],假设当前是第i个陷阱,我们还有j次跳跃机会,那么如果当前使用跳跃机会我们的损失值会降低a[i]-(n-i-(j-1)),其中(n-i-(j-1))就是因为本次跳跃而导致的后续损失增加的值,那么我们就是选择m个a[i]使得\sum a[i]-(n-i-(j-1))最大,对于a[i]-(n-i-(j-1))变形发现等于a[i]+i-(n-j+1),其中n-j+1是不会跟着我们所选择跳跃的位置变化而变化的,所以我们可以直接求出来,至于a[i]+i我们可以直接排序求一下最大的m个陷阱即可。细节见代码:

    动态规划超时代码:

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<cstdio>
    5. #include<cmath>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. const int N=2e5+10;
    10. long long f[2][N];
    11. int a[N];
    12. //f[i][j]表示前i个陷阱中用了j次跳跃后所受到的最小伤害
    13. int main()
    14. {
    15. int T;
    16. cin>>T;
    17. int n,m;
    18. while(T--)
    19. {
    20. scanf("%d%d",&n,&m);
    21. for(int i=1;i<=n;i++)
    22. scanf("%d",&a[i]);
    23. f[0][0]=0;
    24. for(int i=1;i<=n;i++)
    25. for(int j=0;j<=m;j++)
    26. {
    27. if(j==0)
    28. {
    29. f[i&1][j]=f[(i-1)&1][j]+a[i];
    30. continue;
    31. }
    32. f[i&1][j]=min(f[(i-1)&1][j]+a[i],f[(i-1)&1][j-1]+max(0,(n-i)-(m-j)));
    33. }
    34. printf("%lld\n",f[n&1][m]);
    35. }
    36. return 0;
    37. }

    贪心代码:

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<cstdio>
    5. #include<cmath>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. const int N=2e5+10;
    10. int a[N],b[N];
    11. int main()
    12. {
    13. int T;
    14. cin>>T;
    15. int n,m;
    16. while(T--)
    17. {
    18. scanf("%d%d",&n,&m);
    19. long long ans=0;
    20. for(int i=1;i<=n;i++)
    21. scanf("%d",&a[i]),ans+=a[i],b[i]=a[i]+i;
    22. for(int i=0;i<m;i++)
    23. ans+=n-i;
    24. sort(b+1,b+n+1);
    25. for(int i=n;i>n-m;i--)
    26. ans-=b[i];
    27. printf("%lld\n",ans);
    28. }
    29. return 0;
    30. }

  • 相关阅读:
    Angular引入ant.desigin的Transfer穿梭框和轮播图carousel
    LVS+Keepalived群集实验
    tomcat部署war包访问显示404
    【视频图像篇】FastStone Capture屏幕长截图软件
    开通5G网络服务三个月,中国广电交出了什么样的答卷?
    android13(T) SystemUI 运营商显示 bug 修复
    基于SpringBoot的导师双选系统设计与实现
    资深博导:我以为数据预处理是常识,直到遇到自己的学生
    计算机网络期末知识点(第六章)
    为什么你的抖店没流量,不出单怎么办?教你抖音自然流量爆单玩法
  • 原文地址:https://blog.csdn.net/AC__dream/article/details/126963200