• “山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛


    打星队的菜比来补题啦

    A - Seventeen(构造,签到)

    用1~n所有数字用+,-,*,(,),组成计算式使得其得数为17。

    思路:找规律可得,小于4绝对无法组成17,当n为4时,可使得(4+1)*3+2得出17,n为5时,可使得4*5-3*(2-1),对于n为偶数时,可以以4为基础,剩下的相邻两数两两组成(i+1-i)的形式得到1,从而对答案无影响;n为奇数时,则以5为基础,相同操作即可。

    AC Code:

    1. #include <bits/stdc++.h>
    2. typedef long long ll;
    3. const int N=2e5+5;
    4. int n;
    5. int main(){
    6. std::ios::sync_with_stdio(false);
    7. std::cin.tie(0);
    8. std::cin>>n;
    9. if(n<4){
    10. std::cout<<-1<<'\n';
    11. return 0;
    12. }
    13. if(n%2==0){
    14. std::cout<<"(4+1)*3+2";
    15. for(int i=5;i<=n;i+=2){
    16. std::cout<<"*("<<i+1<<"-"<<i<<")";
    17. }
    18. std::cout<<'\n';
    19. }
    20. else{
    21. std::cout<<"4*5-3*(2-1)";
    22. for(int i=6;i<=n;i+=2){
    23. std::cout<<"*("<<i+1<<"-"<<i<<")";
    24. }
    25. std::cout<<'\n';
    26. }
    27. return 0;
    28. }

    os:这种类型的题之前师哥给的题中有类似的,但是我没有及时想到,在做的时候也很长时间没想到4是最小的界限,使得WA了好多发,,就离谱

    K - Coins(规律,暴力枚举)

    A有4种硬币2,3,17,19,B有4种硬币5,7,11,13,有若干组询问x,问谁能用更少的硬币凑出x。

    思路:若同时有a和b两种面值的硬币,且a<b,则每a个b硬币可以用b个a硬币代替,故a硬币在最优解中小于b,所以对于比较小的范围我们可以暴力枚举得到答案,在一个较大的数情况下答案是一定的。

    AC Code:

    1. #include <bits/stdc++.h>
    2. #define INF 0x3f3f3f3f
    3. typedef long long ll;
    4. const int N=1e5+5;
    5. int A[]={0,2,3,17,19};
    6. int B[]={0,5,7,11,13};
    7. int a[N],b[N];
    8. int x,q;
    9. int main(){
    10. std::ios::sync_with_stdio(false);
    11. std::cin.tie(0);
    12. memset(a,INF,sizeof(a));
    13. memset(b,INF,sizeof(b));
    14. a[0]=0,b[0]=0;
    15. for(int i=1;i<=4;i++){
    16. for(int j=A[i];j<=100000;j++){
    17. a[j]=std::min(a[j],a[j-A[i]]+1);
    18. }
    19. }
    20. for(int i=1;i<=4;i++){
    21. for(int j=B[i];j<=100000;j++){
    22. b[j]=std::min(b[j],b[j-B[i]]+1);
    23. }
    24. }
    25. std::cin>>q;
    26. while(q--){
    27. std::cin>>x;
    28. if(x>=100000){
    29. std::cout<<"A"<<'\n';
    30. continue;
    31. }
    32. if(a[x]>=INF&&b[x]>=INF){
    33. std::cout<<-1<<'\n';
    34. }
    35. else if(a[x]==b[x]){
    36. std::cout<<"both"<<'\n';
    37. }
    38. else if(a[x]>b[x]){
    39. std::cout<<"B"<<'\n';
    40. }
    41. else if(a[x]<b[x]){
    42. std::cout<<"A"<<'\n';
    43. }
    44. }
    45. return 0;
    46. }

    os:这个题当时搞了好久到最后终于搞出来了,结果重测的时候被卡了,寄

    H - Counting(桶维护)

    给出k个人的初始坐标, 给出k个人在T秒内的动作,计算每一秒重叠的人的对数。

    思路:直接模拟,每次走之后修改当前状态和下一个状态,注意人的对数是C(n,2)。

    AC Code:

    1. #include <bits/stdc++.h>
    2. #define INF 0x3f3f3f3f
    3. typedef long long ll;
    4. const int N=3e3+5;
    5. const int M=2e3+5;
    6. int n,m,T,k;
    7. int ans[N],x[M],y[M],mp[M][M];
    8. char s[M][N];
    9. int main(){
    10. scanf("%d%d%d%d",&n,&m,&k,&T);
    11. for(int i=0;i<k;i++){
    12. scanf("%d%d",&x[i],&y[i]);
    13. ans[0]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    14. mp[x[i]][y[i]]++;
    15. ans[0]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    16. }
    17. for(int i=0;i<k;i++){
    18. scanf("%s",s[i]);
    19. }
    20. int cnt=1;
    21. for(int j=0;j<T;j++){
    22. ans[cnt]=ans[cnt-1];
    23. for(int i=0;i<k;i++){
    24. ans[cnt]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    25. mp[x[i]][y[i]]--;
    26. ans[cnt]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    27. if(s[i][j]=='U') x[i]--;
    28. else if(s[i][j]=='D') x[i]++;
    29. else if(s[i][j]=='R') y[i]++;
    30. else if(s[i][j]=='L') y[i]--;
    31. ans[cnt]-=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    32. mp[x[i]][y[i]]++;
    33. ans[cnt]+=(mp[x[i]][y[i]]-1)*mp[x[i]][y[i]]/2;
    34. }
    35. ++cnt;
    36. }
    37. for(int i=0;i<=T;i++){
    38. printf("%d\n",ans[i]);
    39. }
    40. return 0;
    41. }

    os:当时做题的时候队友开的计算几何,这个题看都没看,,,完完全全签到啊呜呜呜

    E - Subsegments(思维,桶)

     给定数组a和一个数x,问有多少区间的乘积在模这个东西下得数为x。

    思路:分两种情况讨论:x==0时,计算包含0的区间即可,注意不仅仅是数组中是0,模那个东西等于0也算;x不等于0时,同样以0为分界,对每一段维护前缀积,用map维护桶即可。

    AC Code:

    1. #include <bits/stdc++.h>
    2. #define INF 0x3f3f3f3f
    3. typedef long long ll;
    4. const int N=5e5+5;
    5. const int mod=998244353;
    6. ll n,x,b,res,ans;
    7. ll a[N];
    8. int main(){
    9. std::ios::sync_with_stdio(false);
    10. std::cin.tie(0);
    11. std::cout.tie(0);
    12. std::cin>>n>>x;
    13. if(x==0){
    14. for(int i=1;i<=n;i++){
    15. std::cin>>b;
    16. a[i]=b%mod;
    17. if(a[i]==0) res=i;
    18. ans+=res;
    19. }
    20. }
    21. else{
    22. std::map<int,int>mp;
    23. res=mp[x]=1;
    24. for(int i=1;i<=n;i++){
    25. std::cin>>b;
    26. a[i]=b%mod;
    27. if(a[i]==0){
    28. mp.clear();
    29. res=mp[x]=1;
    30. }
    31. else{
    32. res=res*a[i]%mod;
    33. ans+=mp[res];
    34. ++mp[res*x%mod];
    35. }
    36. }
    37. }
    38. std::cout<<ans<<'\n';
    39. return 0;
    40. }

    os:学习的师哥队的代码,我还是在某些处理上需要加强啊

    J - Football Match(计算几何)

     给出一面旗子的比例,给出A,B两点的坐标,求旗子其他所有点的坐标。

     os:这个题真的是无语,纸质题面和牛客上不一样,,纸质的没有说这个旗子可以旋转,,白费了我们那么长时间,,好叭也是我们不自量力了才会开计算几何题,寄

    思路:根据比例计算线段的长度,可以得到点的坐标。对于这个题而言,我们大可以使用原题给的数据按比例缩放后旋转。思路不难,但是非常麻烦。

    注:对于关于某点旋转,可以采用矩阵旋转直接带入:

    矩阵右乘(x,y)的转置矩阵即可。实际上,我们可以发现,不必考虑顺时针或者逆时针旋转,直接代数,根据角度的正负即可。 

    AC Code:

    1. #include <bits/stdc++.h>
    2. #define INF 0x3f3f3f3f
    3. typedef long long ll;
    4. typedef long double ld;
    5. const double PI=acos(-1);
    6. int t;
    7. ld xa,ya,xb,yb;
    8. ld xx[]={
    9. 30.000000,30.000000,15.000000,16.347084,20.706339,17.179628,18.526712,15.000000,11.473288,12.820372,9.293661,13.652916
    10. };
    11. ld yy[]={
    12. 20.000000,0.000000,16.000000,11.854102,11.854102,9.291796,5.145898,7.708204,5.145898,9.291796,11.854102,11.854102
    13. };
    14. void init(){
    15. ld MN=(6*sin(PI*2/5))/(1+sin(PI/10));
    16. ld PF=MN*sin(PI/10);
    17. ld OP=6*cos(PI*2/5);
    18. ld PG=6*sin(PI*2/5);
    19. ld OF=sqrt(PF*PF+OP*OP);
    20. //F
    21. xx[3]=15+PF;
    22. yy[3]=10+OP;
    23. //G
    24. xx[4]=15+PG;
    25. yy[4]=10+OP;
    26. //H
    27. xx[5]=15+OF*cos(PI/10);
    28. yy[5]=10-OF*sin(PI/10);
    29. //I
    30. xx[6]=15+6*sin(PI/5);
    31. yy[6]=10-6*cos(PI/5);
    32. //J
    33. yy[7]=10-OF;
    34. //K
    35. xx[8]=15-6*sin(PI/5);
    36. yy[8]=10-6*cos(PI/5);
    37. //L
    38. xx[9]=15-OF*cos(PI/10);
    39. yy[9]=10-OF*sin(PI/10);
    40. //M
    41. xx[10]=15-PG;
    42. yy[10]=10+OP;
    43. //N
    44. xx[11]=15-PF;
    45. yy[11]=10+OP;
    46. }
    47. int main(){
    48. init();
    49. scanf("%d",&t);
    50. while(t--){
    51. scanf("%Lf%Lf%Lf%Lf",&xa,&ya,&xb,&yb);
    52. xb-=xa,yb-=ya;
    53. ld sinn=xb,coss=yb;
    54. for(int i=0;i<12;i++){
    55. ld sinx=xx[i];
    56. ld cosx=yy[i];
    57. ld cosp=cosx*coss-sinx*sinn;
    58. ld sinp=sinx*coss+cosx*sinn;
    59. ld ansx=sinp/20+xa;
    60. ld ansy=cosp/20+ya;
    61. printf("%.10Lf %.10Lf%c",ansx,ansy,i==11?'\n':' ');
    62. }
    63. }
    64. return 0;
    65. }

    os:学习的wygg队的代码,简洁而且很清楚,tqllllll!!!

    先这样吧,能力有限,明年省赛再战!

    若有错误请指教,谢谢!

  • 相关阅读:
    手撕AVL树 (C++ 实现)
    Leetcode:【169. 多数元素】
    java类比C++的STL库
    Easyrecovery2022硬盘磁盘U盘免费数据恢复软件
    PMI-ACP练习题(26)
    电脑格式化后文件还能恢复吗?
    22下半年:来长沙建第二支团队与所读的30本书(含哲学文学历史书单/笔记)
    OAK相机:启动报错X_LINK_DEVICE_NOT_FOUND
    PSO算法(优化与探索四*DDPG与GAN)
    基础篇——基础项目解析
  • 原文地址:https://blog.csdn.net/m0_62289613/article/details/125382390