zoukankan      html  css  js  c++  java
  • 伊苏比的梦幻之旅(一)比赛题解

    比赛地址: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;
    }
  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/cs-lyj1997/p/6792127.html
Copyright © 2011-2022 走看看