2024河南省萌新联赛第(六)场 郑州大学

王柳  金牌会员 | 2024-8-27 23:16:32 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 889|帖子 889|积分 2667

2024河南省萌新联赛第(六)场 郑州大学

A.装备二选一(一)

原题链接
题意:

自己的武器可以增长a%暴击率,发生暴击时本次攻击率增长b倍,击败boss的武器可以增长c%暴击率,发生暴击时本次攻击率增长d倍,求boss的输出率是否比自己的武器高
思路:

一个数学问题,一开始一直没看到没有发生暴击时本次也是输出的,用数学思路解决就可以,暴击率乘以增长倍数加上原来的攻击等于该武器的输出率,如果boss的大于自己的输出YES,否则输出NO。
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. signed main()
  6. {
  7.         IOS
  8.         int a,b,c,d;
  9.         cin>>a>>b>>c>>d;
  10.         double x=a*1.0/100*b;
  11.         double y=c*1.0/100*d;
  12.         double x1=(100-a)*1.0/100;
  13.         double y1=(100-c)*1.0/100;
  14.         //cout<<x<<" "<<y<<'\n';
  15.         if(x+x1<y+y1)
  16.         cout<<"YES"<<'\n';
  17.         else
  18.         cout<<"NO"<<'\n';
  19. }
复制代码
B.百变吗喽

原题链接
题意:

给出两个字符串s,t,找出如何将s添加一个字符变成t,求出方案数,并输出应该添加谁人字符和添加到第几位的后面,如果添加到最前面,则是添加到第0位的后面。
思路:

先统计字符串中每个字符的个数,如果t字符串减去s字符串不为1,则输出0;循环字符串,如果该地方两个字符串不同,那么t就是须要添加的字符,在往前循环s字符串,如果与t相等,就说明也可以添加到该字符后面,直到不相等竣事。
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. int a[30],b[30];
  6. signed main()
  7. {
  8.         IOS
  9.         string s,t;
  10.         int ss=0,tt=0,ans=1;
  11.         cin>>s>>t;
  12.         for(int i=0;i<s.size();i++)
  13.         {
  14.                 a[s[i]-'a']++;
  15.         }
  16.         for(int i=0;i<t.size();i++)
  17.         {
  18.                 b[t[i]-'a']++;
  19.         }
  20.         for(int i=0;i<30;i++)
  21.         {
  22.                 ss+=abs(b[i]-a[i]);
  23.         }
  24.         if(ss!=1)
  25.         cout<<"0"<<'\n';
  26.         else
  27.         {
  28.                 char ch;
  29.                 for(int i=0;i<t.size();i++)
  30.                 {
  31.                         if(s[i]!=t[i])
  32.                         {
  33.                                 ch=t[i];
  34.                                 tt=i;
  35.                                 break;
  36.                                
  37.                         }
  38.                 }
  39.                 for(int i=tt-1;i>=0;i--)
  40.                 {
  41.                         if(s[i]==ch)
  42.                         ans++;
  43.                         else
  44.                         break;
  45.                 }
  46.                 cout<<ans<<'\n';
  47.                 for(int i=ans-1;i>=0;i--)
  48.                 {
  49.                         cout<<tt-i<<" "<<ch<<'\n';
  50.                 }
  51.         }
  52. }
复制代码
C.16进制天下

原题链接
题意:

给出两个数n,m分别表示n个月饼,饱食度的和不大于m,接下来n行分别表示每个月饼的饱食度和幸福度,求在饱食度不大于m,并且幸福度为16的倍数时最多吃的月饼的数量
思路:

背包问题请看这
如果出去幸福度不看的话就是一个01背包问题,着实加上幸福度后也不算难,因为须要满足幸福度是16的倍数,所以只须要两个数x,y加起来是16的倍数,所以我们就设饱食度为j时,幸福度与16取模为k时能吃的最多月饼个数,递推方程为:
                                         f                            [                            j                            ]                            [                            k                            ]                            =                            m                            a                            x                            (                            f                            [                            j                            ]                            [                            k                            ]                            ,                            f                            [                            j                            −                            v                            [                            i                            ]                            ]                            [                            (                            k                            −                            w                            [                            i                            ]                            +                            16                            )                                  f[j][k]=max(f[j][k],f[j-v][(k-w+16)%16]+1);                     f[j][k]=max(f[j][k],f[j−v][(k−w+16)
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. const int N=2e5+20;
  6. int v[N],w[N],f[N][20];
  7. signed main()
  8. {
  9.         IOS
  10.         int n,m;
  11.         cin>>n>>m;
  12.         for(int i=0;i<n;i++)
  13.         {
  14.                 int x,y;
  15.                 cin>>x>>y;
  16.                 v[i]=x;
  17.                 w[i]=(y%16);
  18.         }
  19.         f[0][0]=1;
  20.         for(int i=0;i<n;i++)
  21.         {
  22.                 for(int j=m;j>=v[i];j--)
  23.                 {
  24.                         for(int k=0;k<16;k++)
  25.                         {
  26.                                 if(f[j-v[i]][(k-w[i]+16)%16]!=0)
  27.                                 f[j][k]=max(f[j][k],f[j-v[i]][(k-w[i]+16)%16]+1);
  28.                         }
  29.                 }
  30.         }
  31.         int ans=0;
  32.         for(int i=1;i<=m;i++)
  33.         {
  34.                 ans=max(ans,f[i][0]-1);
  35.         }
  36.         cout<<ans<<'\n';
  37. }
复制代码
D.四散而逃

原题链接
题意:

一个数n表示n个格子,接下来n个数表示每个格子里的人数,每次可以选择一个格子使得格子里的人一个往右跑,一个往左跑,选择的格子满足该格子必须有两个人及以上并且不能是两边的格子,问至少多少次才能让全部人都在两边格子,如果不能输出-1
思路:

起首思量是三个格子的特殊情况,如果中间谁品德子是奇数就输出-1,否则输出a[2]/2;多个格子时,如果中间的格子每个都是一个人就输出-1,否则每个格子次数都是(a+1)/2,依次累加,就是答案。
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. const int N=2e5+20;
  6. int a[N];
  7. signed main()
  8. {
  9.         IOS
  10.         int n,s=0,ss=0;
  11.         cin>>n;
  12.         for(int i=1;i<=n;i++)
  13.         cin>>a[i];
  14.         if(n==3)
  15.         {
  16.                 if(a[2]%2!=0)
  17.                 cout<<"-1"<<'\n';
  18.                 else
  19.                 cout<<a[2]/2<<'\n';
  20.         }
  21.         else
  22.         {
  23.                 for(int i=2;i<=n-1;i++)
  24.                 {
  25.                         if(a[i]%2!=0)
  26.                         s++;
  27.                         s+=a[i]/2;
  28.                         if(a[i]==1)
  29.                         ss++;
  30.                 }
  31.                 if(ss==n-2)
  32.                 cout<<"-1"<<'\n';
  33.                 else
  34.                 cout<<s<<'\n';
  35.         }
  36. }
复制代码
F.追寻光的方向

原题链接
题意:

给出一个整数n,表示路灯个数,接下来n个整数表示每个路灯的亮度值,每次回跑到实现范围内最大的亮度值处休息,问到达第n个路灯总共须要休息几次。
思路:

把第2个路灯到第n-1个路灯按亮度值从小到大排序b[n],然后在原来没排序的路等职从第2个到第n个循环,令t=n,如果等于b[t],就让休息次数加1,t–,m=i,继续循环下一个,如果循环到最后一个值不等于b[t],就继续从第m开始循环,直到等于为止,最后输出s.
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. const int N=2e5+20;
  6. int a[N],b[N];
  7. signed main()
  8. {
  9.         IOS
  10.         int n,s=0,m;
  11.         cin>>n;
  12.         for(int i=1;i<=n;i++)
  13.         {
  14.                 cin>>a[i];
  15.                 b[i]=a[i];
  16.         }
  17.         sort(b+2,b+n+1);
  18.         int t=n;
  19.         for(int i=2;i<=n;i++)
  20.         {
  21.                 if(a[i]==b[t])
  22.                 {
  23.                         s++;
  24.                         t--;
  25.                         m=i;
  26.                 }
  27.                 if(i==n&&a[i]!=b[t])
  28.                 {
  29.                         t--;
  30.                         i=m;
  31.                 }
  32.         }
  33.         cout<<s-1<<'\n';
  34. }
复制代码
G.等公交车

原题链接
题意:

给两个数n,m,表示n个站点,m辆车,一分钟一米,n个整数依次递增表示每个站点到出发点的距离,m个整数表示每辆车出发的时间,接下来q次查询,每次查询给出一个时间和站点,求最少须要等多长时间,如果坐不上车,输出TNT
思路:

起首是如果当前到达的时间大于最后一辆车加上中间的路径,那么不可能坐上车,直接输出TNT;令到达的时间减去到该站点的距离,表示一分钟不消等时车应该几点出发,循环车出发的时间,当车出发的时间大于等于改时间时,输出,并竣事循环,因为出发时间是依次递增的,后面出发的车一定等待时间更长。
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. const int N=2e5+20;
  6. int d[N],t[N];
  7. signed main()
  8. {
  9.         IOS
  10.         int n,m,q;
  11.         cin>>n>>m;
  12.         for(int i=1;i<=n;i++)
  13.         cin>>d[i];
  14.         for(int i=1;i<=m;i++)
  15.         cin>>t[i];
  16.         int s=t[m]+d[n];
  17.         cin>>q;
  18.         while(q--)
  19.         {
  20.                 int x,y,ss=INT_MAX;;
  21.                 cin>>x>>y;
  22.                 if(x>s)
  23.                 cout<<"TNT"<<'\n';
  24.                 else if(x>t[m]+d[y])
  25.                 cout<<"TNT"<<'\n';
  26.                 else
  27.                 {
  28.                         int tt=x-d[y];
  29.                         for(int i=1;i<=m;i++)
  30.                         {
  31.                                 if(t[i]-tt>=0)
  32.                                 {
  33.                                         cout<<t[i]-tt<<'\n';
  34.                                         break;
  35.                                 }
  36.                         }
  37.                 }
  38.         }
  39. }
复制代码
I.正义从不打背身

原题链接
题意:

给两个数n,m,n表示有n个对头,m表示m次操作,操作内容:
第i次操作是先把序号为[1,i]的点位置上的对头位置改变,改变规则为:从1,2,3……,i变为i,i-1,……,3,2,1(原来i号位置的对头更换到1号位置……);
然后把[1,i]的点的对头原地旋转180
可以击败正对自己的对头,不可以击中背对自己的对头,P代表正面,B代表背面
思路:

就是打表找规律,规律照旧比力容易的,但我其时因为时间不够给想简单了。正确的规律就是后m+1~n是没有变化的前m个数的前半部分是以m开头,2为公差递减到1或2的等差数列,后半部分是以1,2中剩余的谁人开头,以2为公差递增到m-1。根据这个规律写就可以了。
AC代码:

  1. #include<bits/stdc++.h>
  2. #define int long long
  3. #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
  4. using namespace std;
  5. const int N=2e6+20;
  6. int a[N];
  7. signed main()
  8. {
  9.         IOS
  10.         int n,m;
  11.         cin>>n>>m;
  12.         for(int i=1;i<=n;i++)
  13.         {
  14.                 char ch;
  15.                 cin>>ch;
  16.                 if(ch=='P')
  17.                 a[i]=1;
  18.                 else
  19.                 a[i]=0;
  20.         }
  21.         int tt=m;
  22.         for(int i=1;i<=n;i++)
  23.         {
  24.                 a[i]+=tt;
  25.                 a[i]=a[i]%2;
  26.                 tt--;
  27.                 if(tt==0) break;
  28.         }
  29.         tt=m;
  30.         int f=0;
  31.         for(int i=1;i<=m;i++)
  32.         {
  33.                 cout<<a[tt]<<" ";
  34.                 if(f==0) tt-=2;
  35.                 else
  36.                 {
  37.                         if(tt==1)
  38.                         {
  39.                                 if(m%2==1)
  40.                                 tt+=1;
  41.                                 else
  42.                                 tt+=2;
  43.                         }
  44.                         else
  45.                         tt+=2;
  46.                 }
  47.                 if(tt==0||tt==1)
  48.                 {
  49.                         tt=1;
  50.                         f=1;
  51.                 }
  52.         }
  53.         for(int i=m+1;i<=n;i++)
  54.         cout<<a[i]<<" ";
  55. //        if(m%2==0)
  56. //        tt=m/2;
  57. //        else
  58. //        tt=m/2+1;
  59. //        for(int i=0;i<tt;i++)
  60. //        {
  61. //                if(s[i]=='P')
  62. //                s[i]='B';
  63. //                else
  64. //                s[i]='P';
  65. //        }
  66. //        for(int i=0;i<n;i++)
  67. //        {
  68. //                if(s[i]=='P')
  69. //                cout<<"1"<<" ";
  70. //                else
  71. //                cout<<"0"<<" ";
  72. //        }
  73. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表