• 伊苏比的梦幻之旅(一)比赛题解


    比赛地址:http://qscoj.cn/contest/20/

    第1-1关 教练(小数据)

    分析:a,b只有10^4大小,典型水题,直接计算两个教练的训练效果值再进行比较就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int a,b,p1,p2;
        cin>>a>>b;
        p1=a+b;p2=a*b;
        if (p1>p2) cout<<1<<endl;
        if (p1==p2) cout<<"1/2"<<endl;
        if (p1<p2) cout<<2<<endl;
        return 0;
    }

    第1-2关 教练(中数据)

    分析:a,b有10^18大小,相乘的话会爆long long,比较结果会产生错误。仔细分析一下我们不难判断,如果a和b中有一个为1,假设a为1,那么教练1的训练效果值p1=1+b,教练2的训练效果值p2=1*b=b,无论b为多少,p1总大于p2;如果a,b中最小值为2,假设a为2,p1=2+b,p2=2*b=2b,b>=2时2+b<=2b,只有当b=2时才取等号;如果a,b中最小值大于等于3时,a+b始终会小于a*b,所以只用对a,b进行一下判断就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long a,b;
        cin>>a>>b;
        if (a==1 || b==1) cout<<1<<endl;
        else
            if (a==2 && b==2) cout<<"1/2"<<endl;
            else cout<<2<<endl;
        return 0;
    }

    第1-3关 教练(大数据)

    分析:由第1-2关我们分析出,只需要对a,b的值进行判断就好,但这里a,b的范围为10^418,所以得用字符串的方式进行输入并判断。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        string a,b;
        cin>>a>>b;
        if (a=="1" || b=="1") cout<<1<<endl;
        else
            if (a=="2" && b=="2") cout<<"1/2"<<endl;
            else cout<<2<<endl;
        return 0;
    }

    第2-1关 魔方(小数据)

    分析:购买2-5阶魔方各一个,数出每个魔方的中心块数、棱块数和角块数就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n;
        cin>>n;
        if (n==2) printf("0
    0
    8
    ");
        if (n==3) printf("6
    12
    8
    ");
        if (n==4) printf("24
    24
    8
    ");
        if (n==5) printf("54
    36
    8
    ");
        return 0;
    }

    第2-2关 魔方(中数据)

    分析:一个魔方有6个面,N阶魔方每个面的中心块是一个矩形,其边长为N-2,所以中心块的数量为6*(N-2)*(N-2);一个N阶魔方的立方体有12条棱,每条棱的长度为N-2,所以棱块的数量为12*(N-2);而不管魔方的阶数为多少,其角块数量均为8。N的范围为10^9,其最大计算值不会超过10^18,用long long储存就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long n;
        cin>>n;
        cout<<6*(n-2)*(n-2)<<endl;
        cout<<12*(n-2)<<endl;
        cout<<8<<endl;
        return 0;
    }

    第2-3关 魔方(大数据)

    分析:由第2-2关我们知道一个N阶魔方的中心块数、棱块数和角块数分别为6*(N-2)*(N-2)、12*(N-2)、8。但是N的范围高达10^5109,所以得考虑使用高精度。当然,如果你会JAVA的话用BigInteger这个问题就很好解决了。

    C++标程:

    #include<bits/stdc++.h>
    using namespace std;
    int a[12000],b[12000],z[12000],l[12000];
    int main()
    {
        string s;
        int len,i,j;
        bool flag;
        cin>>s;len=s.length();
        for(i=0;i<len;i++)
        {
            a[i]=s[len-1-i]-48;
            b[i]=a[i];
        }
        b[0]-=2;j=0;
        while(b[j]<0)
        {
            b[j]+=10;j++;b[j]--;
        }
        for(i=0;i<len;i++)
            l[i]=b[i]*12;
        for(i=0;i<len+2;i++)
        {
            j=l[i]/10;l[i]%=10;l[i+1]+=j;
        }
        for(i=0;i<len;i++)
         for(j=0;j<len;j++)
            z[i+j]+=b[i]*b[j];
        for(i=0;i<2*len;i++)
            z[i]*=6;
        for(i=0;i<2*len;i++)
        {
            j=z[i]/10;z[i]%=10;z[i+1]+=j;
        }
        flag=false;
        for(i=11111;i>=0;i--)
        {
            if (i==0 || z[i]) flag=true;
            if (flag) printf("%d",z[i]);
        }
        printf("
    ");
        flag=false;
        for(i=11111;i>=0;i--)
        {
            if (i==0 || l[i]) flag=true;
            if (flag) printf("%d",l[i]);
        }
        printf("
    ");
        cout<<8<<endl;
        return 0;
    }

    JAVA标程:

    import java.util.*;
    import java.math.*;
    public class Main{
        public static void main(String agrs[]){
            Scanner cin=new Scanner(System.in);
            BigInteger a,b,c,d;
            a=cin.nextBigInteger();
            b=a.subtract(BigInteger.valueOf(2));
            c=b.multiply(b);
            c=c.multiply(BigInteger.valueOf(6));
            d=b.multiply(BigInteger.valueOf(12));
            System.out.println(c);
            System.out.println(d);
            System.out.println(8);
        }
    }

    第3-1关 回文数(小数据)

    分析:L,R的数据范围只有1-13,我们都可以手算出其中的回文数:1、2、3、4、5、6、7、8、9、11,所以直接for一遍统计答案就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int l,r,i,cnt;
        cin>>l>>r;cnt=0;
        for(i=l;i<=r;i++)
            if (i<=9 || i==11) cnt++;
        cout<<cnt<<endl;
        return 0;
    }

    第3-2关 回文数(中数据)

    分析:因为L,R的范围是10^7,可以从L循环到R进行线性判断每一个数是否为回文数,判断的方式为将一个数的每一位进行分解,再从头开始和从尾比较其对应位置是否数字相同。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int l,r,i,j,k,s,ans,high;
        int a[10];
        bool flag;
        cin>>l>>r;ans=0;
        for(i=l;i<=r;i++)
        {
            j=i;s=1e7;
            for(k=7;k>=0;k--)
            {
                a[k]=j/s;
                j%=s;s/=10;
            }
            for(high=7;high>=1;high--)
                if (a[high]) break;
            flag=true;
            for(j=0,k=high;j<k;j++,k--)
                if (a[j]!=a[k]) flag=false;
            if (flag) ans++;
        }
        cout<<ans<<endl;
        return 0;
    }

    第3-3关 回文数(大数据)

    分析:因为L,R的数据范围为10^13,所以直接for肯定会超时。回文的特点是,前一半和后一半是相等的。由样例3可知,1到10^13的回文数总数为10999998。所以,我们可以考虑把1到10^13的所有回文数全部枚举出来,再判断其是否在[L,R]区间内。枚举回文数的方法为长度为1位的数字枚举到长度为13位的数字,对于每种长度,首位和末尾可以取1到9,中间各对称位置可以取0到9,用DFS的方式进行枚举就好。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    long long l,r,ans,res;
    long long ten[15];
    int a[15];
    void huiwen(int s,int k)
    {
        int i;
        if (s==(k+1)/2)
        {
            res=0;
            for(i=0;i<k;i++)
                res+=a[i]*ten[i];
            if (res>=l && res<=r) ans++;
            return ;
        }
        if (s)
        {
            for(i=0;i<=9;i++)
            {
                a[s]=a[k-1-s]=i;
                huiwen(s+1,k);
            }
        }
        else
        {
            for(i=1;i<=9;i++)
            {
                a[s]=a[k-1-s]=i;
                huiwen(s+1,k);
            }
        }
    }
    int main()
    {
        int i;
        cin>>l>>r;
        ten[0]=1;
        for(i=1;i<=13;i++)
            ten[i]=ten[i-1]*10;
        for(i=1;i<=13;i++)
            huiwen(0,i);
        cout<<ans<<endl;
        return 0;
    }

    第4-1关 睡觉(小数据)

    分析:N的数据范围只有1-4,而样例已经告诉了你N为1和N为3时的答案,N为2时很轻易能算出答案为3*3=9,所以只需用四层for循环算出N=4的答案就行了。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,ans,a,b,c,d;
        cin>>n;ans=0;
        if (n==1) ans=3;
        if (n==3) ans=21;
        if (n==2) ans=3*3;
        if (n==4)
        {
            for(a=1;a<=3;a++)
                for(b=1;b<=3;b++)
                    for(c=1;c<=3;c++)
                        for(d=1;d<=3;d++)
                         if (!((a!=b && b!=c && a!=c) || (b!=c && b!=d && c!=d))) ans++;
        }
        cout<<ans<<endl;
        return 0;
    }

    第4-2关 睡觉(中数据)

    分析:N的数据范围为1-13,小卿卿每天可能跟三种不同的娃娃一起睡觉,所以理论上最大有3^13=1594323种可能性。用DFS的方式就可以统计出答案。

    #include<bits/stdc++.h>
    using namespace std;
    int ans,n;
    int a[15];
    void dfs(int k)
    {
        if (k==n+1)
        {
            ans++;return ;
        }
        for(int i=1;i<=3;i++)
        {
            a[k]=i;
            if (k>2 && a[k]!=a[k-1] && a[k]!=a[k-2] && a[k-1]!=a[k-2]) continue;
            dfs(k+1);
        }
    }
    int main()
    {
        cin>>n;
        dfs(1);
        cout<<ans<<endl;
    }

    第4-3关 睡觉(大数据)

    分析:N的数据范围为1-31,用第4-2关DFS的方法肯定会超时,而这道题后面每天的睡觉方式跟前面的睡觉方式有联系。所以我们可以采用DP的方式解决这道问题。在某一天,小卿卿要选择睡觉的娃娃时,如果之前两天睡觉的娃娃相同,那么她这一天可以跟任一娃娃一起睡觉,其最近三天最多只跟两种娃娃睡过觉;如果之前两天睡觉的娃娃不同,那么她这一天不能跟剩下那个之前两天没睡过觉的娃娃一起睡觉。所以,我们可以设dp1[i]为前i天最后两天睡觉娃娃相同的方案数,dp2[i]为前i天最后两天睡觉娃娃不相同的方案数。dp1[i]+dp2[i]就是前i天的睡觉方案总数,其转移方程为dp1[i]=dp1[i-1]+dp2[i-1];dp2[i]=2*dp1[i-1]+dp2[i-1]。

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        long long dp1[33],dp2[33];
        int i,n;
        dp1[1]=3;dp2[1]=0;
        cin>>n;
        for(i=2;i<=n;i++)
        {
            dp1[i]=dp1[i-1]+dp2[i-1];
            dp2[i]=2*dp1[i-1]+dp2[i-1];
        }
        cout<<dp1[n]+dp2[n]<<endl;
        return 0;
    }
  • 相关阅读:
    HDU
    CodeForces
    CodeForces
    TensorFlow下利用MNIST训练模型并识别自己手写的数字
    李宏毅机器学习笔记2:Gradient Descent(附带详细的原理推导过程)
    李宏毅机器学习笔记1:Regression、Error
    tensorflow相关API的学习
    解决winscp中普通用户无法上传、删除、移动文件
    2019最新最全HUSTOJ本地及云端服务器搭建(基于腾讯云服务器)
    解决Ubuntu无法进行SSH连接的问题(以及如何使用SSH)
  • 原文地址:https://www.cnblogs.com/cs-lyj1997/p/6792127.html
Copyright © 2020-2023  润新知