Gym 102263 - ArabellaCPC 2019 题解

A - Is It Easy ?(签到题)

#include<iostream>
#include<algorithm>
 using namespace std;
 int main()
 {
     int n,m;
     cin>>n>>m;
     cout<<n*m;
 }
View Code

B. Road to Arabella(博弈论)

思路:

只有$n-k≤1$并且$n$不是偶数的情况下,后手才能赢

#include<iostream>
#include<algorithm>
 using namespace std;
 int main()
 {
     int t,n,k;
     cin>>t;
     while(t--){
         cin>>n>>k;
         if((n==k||n==k+1)&&n%2==0) cout<<"Ayoub"<<endl;
         else cout<<"Kilani"<<endl;
     }
 }
View Code

C. Check The Text(模拟)

#include<iostream>
#include<algorithm>
 using namespace std;
 int main()
 {
     string s1,s2="",s;
     int n,t;
     cin>>n;
     getchar();
     getline(cin,s1);
     cin>>t;
     int flag=0;
     while(t--){
         cin>>s;
         if(s[0]=='B'){
             if(s2.size()) s2.pop_back();
         }
        else if(s[0]=='C') flag^=1;
        else if(s[0]=='S') s2+=" ";
        else{
            if(flag==0) s2+=s;
            else s2+=(s[0]-'a'+'A');
        }
     }
    if(s2.compare(s1)==0) cout<<"Correct";
    else cout<<"Incorrect";
 }
View Code

D. Meeting Bahosain(思维+GCD)

思路:

假设我们想用数组$b$中的元素去表示一个数$x$,就可以写成$x=k1*b[1]+k2*b[2].....$也可以写成$x=k*gcd(b[1],b[2]...b[n])$

那么我们只要需要数组$a$中,任意两个元素之间的差值(可以用$gcd(a[1],a[2]...a[n])$来表示)是否能整除$gcd(b[1],b[2]...b[n])$即可

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n,m,g1,g2,temp;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&temp);
        if(i==1) g1 = temp;
        else g1=__gcd(g1,temp);
    }
    for(int i=1;i<=m;i++){
        scanf("%d",&temp);
        if(i==1) g2=temp;
        else g2=__gcd(g2,temp);
    }
    if(g1%g2==0||n==1) printf("Yes\n");
    else printf("No\n");
    return 0;
}
View Code

G. Card Game(数学期望)

思路:

最后的期望公式为:$\frac{\sum i*(i-1)}{n},2≤i≤n$

#include<iostream>
#include<algorithm>
#include <iomanip>
 using namespace std;
 int main()
 {
     int n;
     cin>>n;
    long double ans=0,y=n;
     for(int i=1;i<=n;i++){
         long double x=i;
         ans+=x*(x-1)/y;
     }
    cout<<fixed<<setprecision(10)<<ans;
 }
View Code

 H. Steaks(思维)

思路:

当$n≥2*k$时,只要花$10$分钟就好了,否则一块牛排需要煎$5$分钟

#include<iostream>
#include<algorithm>
 using namespace std;
 typedef long long ll;
 int main()
 {
     ll n,m;
     cin>>n>>m;
     if(n>2*m) cout<<(n+m-1)/m*5;
    else cout<<10;
  } 
View Code

I. Bashar and Hamada(思维)

思路:

有点类似于$2018$年焦作站的一道题

先将数组排序,然后一大一小放置即可

#include<iostream>
#include<algorithm>
 using namespace std;
 typedef long long ll;
 const int maxn=3e5+10;
 ll a[maxn];
 int main()
 {
     ll n,ans=0,last,flag=0;
     scanf("%lld",&n);
     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
     sort(a+1,a+1+n);
     last=ans=a[n]-a[1];
     int l=2,r=n-1;
     cout<<ans<<" ";
     while(l<=r){
         if(flag==0){
             ans+=last;
             l++;
         } 
         else{
             last+=a[r]-a[l-1];
             ans+=last;
             r--;
         }    
        cout<<ans<<" ";
        flag^=1;
     }
    return 0;
 }
View Code

J. Thanos Power(DP)

思路:

想要得到第$i$位上的数$x$有两种方法

①直接加$x$次$10^{i}$

②先得到$10^{i+1}$,再用减法得到,需要进行$10-x+1$次操作

我们假设$dp[0][i]$,是以第①种方式得到$x$;$dp[1][i]$是以第二种方式得到$x$

那么递推式就为:

$dp[0][i]=s[i]+min(dp[0[[i-1[,dp[1][i-1])$

$dp[1][i]=10-s[i]+min(dp[0][i-1]+1,dp[0][i-1]-1)$ 

因为上一位是由方式①得到,我们还需要在上一位加上一再通过减法得到;如果上一位是由方式二得到,我们再上一位加上一,上一位就可以少进行一次减法,所以减一

#include<iostream>
#include<algorithm>
 using namespace std;
 const int maxn=1e5+10;
 int dp[2][maxn];
 string s;
 int main()
 {
     cin>>s;
     dp[0][0]=s[0]-'0';
     dp[1][0]=10-(s[0]-'0')+1;
     for(int i=1;i<s.length();i++){
         dp[0][i]=s[i]-'0'+min(dp[0][i-1],dp[1][i-1]);
         dp[1][i]=10-(s[i]-'0')+min(dp[0][i-1]+1,dp[1][i-1]-1);
     }
    cout<<min(dp[0][s.length()-1],dp[1][s.length()-1]);
 }
View Code

 M. Two Operations(思维)

思路:

统计每个字符的个数,从小到大(除了z)逢$2$向更大的字符进一位

#include<iostream>
#include<algorithm>
#include<map>
 using namespace std;
 map<int,int> m;
 int main()
 {
     string s;
     cin>>s;
     for(int i=0;i<s.length();i++) m[s[i]-'a']++;
     for(int i=0;i<25;i++){
         int num=m[i];
         m[i+1]+=num/2;
         m[i]=num%2;
     }
    for(int i=25;i>=0;i--)
        for(int j=1;j<=m[i];j++)
            printf("%c",'a'+i);
    return 0;
  } 
View Code

 

posted @ 2020-07-11 00:38  overrate_wsj  阅读(413)  评论(0编辑  收藏  举报