zoukankan      html  css  js  c++  java
  • JSU省赛队员选拔赛个人赛1(Coin Change、Fibbonacci Number、Max Num、单词数、无限的路、叠筐)

    JSU省赛队员选拔赛个人赛1

    一、题目概述:

        A、Coin Change(暴力求解、动态规划)
        B、Fibbonacci Number(递推求解)

        C、Max Num(排序、比较)

        D、单词数(字符串比较、库函数运用)

        E、无限的路(平面几何)

        F、叠筐(规律输出)

    二、解题报告:


    A、Coin Change

          给一个钱的总金额,求出用100个以内的50分、25分、10分、5分、1分硬币拼成该金额的不同拼法。

          直接暴力,打表什么的都是浮云。开始总觉得用暴力求解显得自己没风度,不够高端霸气上档次。当面临各种WA时,什么都是浮云,唯有AC才是王道。

           用i,j,k,x,y分别表示50分、25分、10分、5分、1分硬币的数量,用四重循环直接暴力(不用五层。剩下的变量直接可以求得)。当y=n-x*5-k*10-j*25-i*50;并且y不小于0,硬币总数不大于100的时候,表示这种拼法是可以的,计数变量sum自加一,最后直接输出计数变量即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int main()
    {
        int n;
        int i,j,k,x,y;
        while(cin>>n)
        {
            __int64 sum=0;
            for(i=0; i<=n/50; i++)   //50分的硬币i个
                for(j=0; j<=n/25; j++)   //25分的硬币j个
                    for(k=0; k<=n/10; k++)   //10分的硬币k个
                        for(x=0; x<=n/5; x++)   //5分的硬币x个
                        {
                            y=n-x*5-k*10-j*25-i*50;  //一分的硬币y个
                            if(y>=0&&i+j+k+x+y<=100)sum++; //满足要求,这种拼法是可以的
                        }
            cout<<sum<<endl;
        }
        return 0;
    }
    


    B、
    Fibbonacci Number

         没什么好讲的,直接用公式来算就好了。

         不过要注意两点:

             (1)先打表,后面要用到的话,直接输出即可。避免超时。

             (2)要用64为位int,题目最大输出第50个斐波那契数,该数超出32位int的存储范围。否则,数据溢出造成WA。

    #include<iostream>
    using namespace std;
    int main()
    {
        __int64 f[55];
        int i,n;
        f[0]=0;
        f[1]=1;
        for(i=2;i<55;i++)f[i]=f[i-1]+f[i-2];  //直接打表
        while(cin>>n&&n!=-1)cout<<f[n]<<endl;  //直接按表输出
        return 0;
    }


    C、Max Num

          简单题,直接比较就好了。

          t组数据,每组数据n个,然是n个数据,求n个数据中的最大值。

           对于每一组数据,用一个初始值为0(输入的值都不小于0)的max比较处理。逐个输入n个数,每个数和max比较,要是比max大,就替换max的值。后面直接输出max的值就好了。注意用double处理数据。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int main()
    {
        int t,n;
        double x,max;
        cin>>t;
        while(t--)
        {
            max=0;
            cin>>n;
            while(n--)
            {
                cin>>x;
                if(x>max)max=x;  //直接比较替换
            }
            printf("%.2lf
    ",max);  //直接输出
        }
        return 0;
    }
    


    D、
    单词数

          稍难的题目,数单词不难,要是常规句式(没有空格),直接数空格就好,单词数=空格数+1;

         问题是,这里要的是不同的单词的种类(句子中还可能有多个空格隔开两个单词,句子的前后端也可能有空格,一个回车结束一个句子)。一般的药已经治不了他了,要想做,不放弃治疗,只能用“抗生素”了。用到sscanf,从字符数组中读取字符串,用到set容器判断该单词前面是否出现过。

    (1)用gets输入数据,一个gets结束就代表一个案例输入完成(最好把用来存储的数组开大点)。

    (2)用sscanf(需要起始位置)从前到后从数组中读出字符串(遇到空格读取就结束),人工跳过空格。

    (3)用set判断先下读取的单词是否在前面出现过,要是没有出现过,直接压入容器,计数变量(记得初始化啊)加1。否则直接跳过。

    (4)最后输出计数变量的值即可。

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<set>
    using namespace std;
    char f[100000000];
    int main()
    {
        //freopen("in.txt","r",stdin);
        __int64 n;
        int i,j;
        char a[1000];
        while(gets(f)&&f[0]!='#')  //输入案例数据,遇到“#”时,程序结束
        {
            n=0;  //计数变量初始化
            set<string> s;  //定义容器s
            int len=strlen(f);   //求出输入数据的长度
            for(i=0; i<len; i++)  //“逐个”检索
            {
                if(f[i]==' ')continue;  //跳过空格
                sscanf(f+i,"%s",a);  //读取字符串
                if(!s.count(a))  //判断字符串是否在前面出现过(没有出现过)
                { 
                    n++;     //计数变量加1
                    s.insert(a);   //压入容器
                }
                i=i+strlen(a)-1;  //跳过已处理的字符串
            }
            cout<<n<<endl;   //输出计数变量即可
        }
        return 0;
    }
    


    E、无限的路


    集合题,郁闷了很久。所有的点都在直线x+y=b上。。。

    先处理最特殊的(0,0)点

    后面求的时候分成4段

    (1)前残余段

    (2)中间直线x+y=b的线段总长度

    (3)中间连接(2)中直线的线段的总长度

    (4)后残余短

    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    double f(int x,int y)
    {
        return sqrt(x*x+y*y);
    }
    int main()
    {
        int t;
        int x,y;
        int x1,y1,x2,y2;
        double l;
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            l=0;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            x=x1+y1;
            y=x2+y2;
            if(y<x)
            {
                swap(x1,x2);
                swap(y1,y2);
            }
            if(x1==0&&y1==0)
            {
                l+=1;
                x1=0;
                y1=1;
            }
            if(x1+y1==x2+y2)
                l+=f(x1-x2,y1-y2);
            else
            {
                x=x1+y1;
                y=x2+y2;
                for(i=x+1; i<y; i++)
                    l+=f(i,i);
                for(i=x; i<y; i++)
                    l+=f(i,i+1);
                l+=f(y1,y1);
                l+=f(x2,x2);
            }
            printf("%.3lf
    ",l);
        }
        return 0;
    }
    


    F、叠筐

    就是圈一圈的输出的意思,用二维数组存储图案,一圈一圈的赋值。从里到外,一圈赋完后改变填充值。

    注意n=1时的特殊处理

    注意输出格式:

    (1)案例间要换行

    (2)“剪角”

    #include<stdio.h>
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n,i,j;
        char a[2],b[2],c;
        char pi[85][85];
        int f=0;
        while(scanf("%d%s%s",&n,a,b)!=EOF)
        {
            if(f)printf("
    ");   //案例间的换行
            if(n==1)  //要是只有1个
                printf("%c
    ",a[0]);
            else
            {
                c=a[0];
                for(i=n/2; i>=0; i--)  //从里到外(填充)
                {
                    for(j=i; j<=n-i-1; j++)
                    {
                        pi[i][j]=c;  //上面一行
                        pi[n-i-1][j]=c;   //下面一行
                        pi[j][i]=c;   //左边一列
                        pi[j][n-i-1]=c;   //右边一列
                    }
                    if(c==a[0])c=b[0];   //更换“填充物”
                    else c=a[0];
                }
                //pi[n/2][n/2]=a[0];
                for(i=0; i<n; i++)
                {
                    for(j=0; j<n; j++)
                    {
                        if((i==0&&j==0)||(i==0&&j==n-1)||(i==n-1&&j==0)||(i==n-1&&j==n-1))  //“剪角”
                            printf(" ");
                        else
                            printf("%c",pi[i][j]);
                    }
                    printf("
    ");
                }
            }
            f=1;
        }
        return 0;
    }
    











  • 相关阅读:
    rapidjson 的练习
    在Struts2中集成Spring详细讲解
    AJAX实例入门
    Redhat Enterprise Linux中如何关闭SELinux?
    C3P0连接池详细配置
    hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别
    107个常用Javascript语句
    车祸 shit
    JAVASCRIPT实现XML分页
    javabeans的运用
  • 原文地址:https://www.cnblogs.com/pangblog/p/3320160.html
Copyright © 2011-2022 走看看