zoukankan      html  css  js  c++  java
  • 算法笔记 上机训练实战指南 第3章 入门篇(1)--入门模拟 学习笔记 3.1简单模拟

    1001 害死人不偿命的(3n+1)猜想 (15分)

    卡拉兹(Callatz)猜想:

    对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 ( 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (,以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

    我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

    输入格式:

    每个测试输入包含 1 个测试用例,即给出正整数 n 的值。

    输出格式:

    输出从 n 计算到 1 需要的步数。

    输入样例:

    3

    输出样例:

    5
    #include<cstdio>
    int main(){
        int n,count=0;
        scanf("%d",&n);
        while(n!=1){
            if(n%2==0){
                n = n/2;
                count++;
            }else{
                n = (3*n+1)/2;
                count++;
            }
        }
        printf("%d",count);
        return 0;
    }
    1011 A+B 和 C (15分)

    给定区间 [−] 内的 3 个整数 A、B 和 C,请判断 A+B 是否大于 C。

    输入格式:

    输入第 1 行给出正整数 T (≤),是测试用例的个数。随后给出 T 组测试用例,每组占一行,顺序给出 A、B 和 C。整数间以空格分隔。

    输出格式:

    对每组测试用例,在一行中输出 Case #X: true 如果 A+B>C,否则输出 Case #X: false,其中 X 是测试用例的编号(从 1 开始)。

    输入样例:

    4
    1 2 3
    2 3 4
    2147483647 0 2147483646
    0 -2147483648 -2147483647

    输出样例:

    Case #1: false
    Case #2: true
    Case #3: true
    Case #4: false
    
    #include<cstdio>
    int main(){
        int T,tcase=1;
        scanf("%d",&T);
        while(T--){
            long long a,b,c;
            scanf("%lld%lld%lld",&a,&b,&c);
            if(a+b>c){
                printf("Case #%d: true
    ",tcase);
            }else{
                printf("Case #%d: false
    ",tcase);
            }
            tcase++;
        }
        return 0;
    }
    1016 部分A+B (15分)
     

    正整数 A 的“DA​​(为 1 位整数)部分”定义为由 A 中所有 DA​​ 组成的新整数 PA​​。例如:给定 8,DA​​=6,则 A 的“6 部分”PA​​ 是 66,因为 A 中有 2 个 6。

    现给定 A、DA​​、B、DB​​,请编写程序计算 PA​​+PB​​。

    输入格式:

    输入在一行中依次给出 A、DA​​、B、DB​​,中间以空格分隔,其中 0。

    输出格式:

    在一行中输出 PA​​+PB​​ 的值。

    输入样例 1:

    3862767 6 13530293 3

    输出样例 1:

    399

    输入样例 2:

    3862767 1 13530293 8

    输出样例 2:

    0
    #include<cstdio>
    #include<cmath>
    int main(){
        long long A,B;
        int DA,DB;
        scanf("%lld%d%lld%d",&A,&DA,&B,&DB);
        int PA=0,PB=0; 
        int i=0;
        while(A!=0){
            if(A%10 == DA){
                PA = PA + DA*pow(10,i);
                i++;
            }
            A = A/10;
        }
        i = 0;
        while(B!=0){
            if(B%10 == DB){
                PB = PB + DB*pow(10,i);
                i++;
            }
            B = B/10;
        }
        printf("%d
    ",PA+PB);
        return 0;
    }
    1026 程序运行时间 (15分)
     

    要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick,即“时钟打点”。同时还有一个常数 CLK_TCK,给出了机器时钟每秒所走的时钟打点数。于是为了获得一个函数 f 的运行时间,我们只要在调用 f 之前先调用 clock(),获得一个时钟打点数 C1;在 f 执行完成后再调用 clock(),获得另一个时钟打点数 C2;两次获得的时钟打点数之差 (C2-C1) 就是 f 运行所消耗的时钟打点数,再除以常数 CLK_TCK,就得到了以秒为单位的运行时间。

    这里不妨简单假设常数 CLK_TCK 为 100。现给定被测函数前后两次获得的时钟打点数,请你给出被测函数运行的时间。

    输入格式:

    输入在一行中顺序给出 2 个整数 C1 和 C2。注意两次获得的时钟打点数肯定不相同,即 C1 < C2,并且取值在 [。

    输出格式:

    在一行中输出被测函数运行的时间。运行时间必须按照 hh:mm:ss(即2位的 时:分:秒)格式输出;不足 1 秒的时间四舍五入到秒。

    输入样例:

    123 4577973

    输出样例:

    12:42:59
    #include<cstdio>
    int main(){
        int c1,c2;
        scanf("%d%d",&c1,&c2);
        int ans = c2-c1;
        if(ans%100>=50){
            ans = ans/100+1;
        }else{
            ans = ans/100;
        }
        printf("%02d:%02d:%02d
    ",ans/3600,ans%3600/60,ans%60);
        return 0;
    }
    1046 划拳 (15分)
     

    划拳是古老中国酒文化的一个有趣的组成部分。酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。

    下面给出甲、乙两人的划拳记录,请你统计他们最后分别喝了多少杯酒。

    输入格式:

    输入第一行先给出一个正整数 N(≤),随后 N 行,每行给出一轮划拳的记录,格式为:

    甲喊 甲划 乙喊 乙划
    
     

    其中是喊出的数字,是划出的数字,均为不超过 100 的正整数(两只手一起划)。

    输出格式:

    在一行中先后输出甲、乙两人喝酒的杯数,其间以一个空格分隔。

    输入样例:

    5
    8 10 9 12
    5 10 5 10
    3 8 5 12
    12 18 1 13
    4 16 12 15

    输出样例:

    1 2
    #include<cstdio>
    int main(){
        int n;
        scanf("%d",&n);
        int a1,a2,b1,b2;
        int faia=0,faib=0;
        for(int i=0;i<n;i++){
            scanf("%d%d%d%d",&a1,&a2,&b1,&b2);
            if(a1+b1 == a2 && a1+b1 != b2){
                faib++;
            }else if(a1+b1 == b2 && a1+b1 != a2){
                faia++;
            }
        }
        printf("%d %d",faia,faib);
        
        return 0;
    }
    1008 数组元素循环右移问题 (20分)
     

    一个数组A中存有N(>)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥)个位置,即将A中的数据由(A0​​A1​​AN1​​)变换为(ANM​​AN1​​A0​​A1​​ANM1​​)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

    输入格式:

    每个输入包含一个测试用例,第1行输入N(1)和M(≥);第2行输入N个整数,之间用空格分隔。

    输出格式:

    在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。

    输入样例:

    6 2
    1 2 3 4 5 6

    输出样例:

    5 6 1 2 3 4
    #include<cstdio>
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        int a[110];
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        m = m%n;
        int count=0;
        for(int i=n-m;i<n;i++){
            printf("%d",a[i]);
            count++;
            if(count < n)
                printf(" ");
        }
        for(int i=0;i<n-m;i++){
            printf("%d",a[i]);
            count++;
            if(count < n)
                printf(" ");
        }
        return 0;
    }
    1012 数字分类 (20分)
     

    给定一系列正整数,请按要求对数字进行分类,并输出以下 5 个数字:

    • A1​​ = 能被 5 整除的数字中所有偶数的和;
    • A2​​ = 将被 5 除后余 1 的数字按给出顺序进行交错求和,即计算 n1​​n2​​+n3​​n4​​⋯;
    • A3​​ = 被 5 除后余 2 的数字的个数;
    • A4​​ = 被 5 除后余 3 的数字的平均数,精确到小数点后 1 位;
    • A5​​ = 被 5 除后余 4 的数字中最大数字。

    输入格式:

    每个输入包含 1 个测试用例。每个测试用例先给出一个不超过 1000 的正整数 N,随后给出 N 个不超过 1000 的待分类的正整数。数字间以空格分隔。

    输出格式:

    对给定的 N 个正整数,按题目要求计算 A1​​~A5​​ 并在一行中顺序输出。数字间以空格分隔,但行末不得有多余空格。

    若其中某一类数字不存在,则在相应位置输出 N

    输入样例 1:

    13 1 2 3 4 5 6 7 8 9 10 20 16 18

    输出样例 1:

    30 11 2 9.7 9

    输入样例 2:

    8 1 2 4 5 6 7 9 16

    输出样例 2:

    N 11 2 N 9
    #include<cstdio>
    int main(){
        int n;
        scanf("%d",&n);
        int count[5] = {0};
        int ans[5] = {0};
        int flag = 1;
        while(n--){
            int temp;
            scanf("%d",&temp);
            if(temp%5 == 0 && temp%2==0){
                ans[0] = ans[0] + temp;
                count[0]++;
            }else if(temp%5 == 1){
                ans[1] = ans[1] + flag*temp;
                flag = -flag;
                count[1]++;
            }else if(temp%5 == 2){
                ans[2]++;
                count[2]++;
            }else if(temp%5 == 3){
                count[3]++;
                ans[3] = ans[3]+temp;
            }else if(temp%5 == 4){
                if(temp > ans[4]){
                    ans[4] = temp;
                    count[4]++;
                }
            }
        }
        for(int i=0;i<5;i++){
            if(count[i]==0 && i==4){
                printf("N");
                continue;
            }
            if(count[i]==0 && i<4){
                printf("N ");
                continue;
            }
            if(i==3){
                printf("%.1f ",(double)ans[3]/count[3]);
            }else if(i==4){
                printf("%d",ans[i]);
            }else{
                printf("%d ",ans[i]);
            }
        }
        return 0;
    }
    1018 锤子剪刀布 (20分)
     

    大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:

    FigCJB.jpg

    现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。

    输入格式:

    输入第 1 行给出正整数 N(≤),即双方交锋的次数。随后 N 行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C 代表“锤子”、J 代表“剪刀”、B 代表“布”,第 1 个字母代表甲方,第 2 个代表乙方,中间有 1 个空格。

    输出格式:

    输出第 1、2 行分别给出甲、乙的胜、平、负次数,数字间以 1 个空格分隔。第 3 行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有 1 个空格。如果解不唯一,则输出按字母序最小的解。

    输入样例:

    10
    C J
    J B
    C B
    B B
    B C
    C C
    C B
    J B
    B C
    J J
    
     

    输出样例:

    5 3 2
    2 3 5
    B B

    #include<cstdio>
    int change(char c){
        if(c=='B'){
            return 0;
        }else if(c == 'C'){
            return 1;
        }else if(c == 'J'){
            return 2;
        }
    } 
    int main(){
        int n;
        char mp[3]={'B','C','J'};
        scanf("%d",&n);
        char jia,yi;
        int jiacondition[3]={0},yicondition[3]={0};//记录甲乙的胜平负次数
        int handjia[3]={0},handyi[3]={0};//记录甲乙获胜的手势 
        while(n--){
            getchar();
            scanf("%c %c",&jia,&yi);
            int hjia,hyi;
            hjia = change(jia);
            hyi = change(yi);
            if(hjia == hyi){
                jiacondition[1]++;
                yicondition[1]++;
            }else if((hjia+1)%3 == hyi){
                jiacondition[0]++;
                yicondition[2]++;
                handjia[hjia]++;
            }else if((hyi+1)%3 == hjia){
                yicondition[0]++;
                jiacondition[2]++;
                handyi[hyi]++;
            }
        }
        printf("%d %d %d
    ",jiacondition[0],jiacondition[1],jiacondition[2]);
        printf("%d %d %d
    ",yicondition[0],yicondition[1],yicondition[2]);
        int id1=0,id2=0;
        for(int i=0;i<3;i++){
            if(handjia[i] > handjia[id1]) id1 = i;
            if(handyi[i] > handyi[id2]) id2 = i;
        }
        printf("%c %c",mp[id1],mp[id2]);
        return 0;
    }
    1046 Shortest Distance (20分)
     

    The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains an integer N (in [3]), followed by N integer distances D1​​ D2​​ ⋯ DN​​, where Di​​ is the distance between the i-th and the (-st exits, and DN​​ is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (≤), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 1.

    Output Specification:

    For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.

    Sample Input:

    5 1 2 4 14 9
    3
    1 3
    2 5
    4 1

    Sample Output:

    3
    10
    7
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN = 100010;
    int dis[MAXN],A[MAXN];
    int main(){
        int n;
        int sum=0,query;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&A[i]);
            sum = sum + A[i];
            dis[i] = sum;
        }
        int left,right;
        scanf("%d",&query);
        for(int i=0;i<query;i++){
            scanf("%d%d",&left,&right);
            if(left >right)
                swap(left,right);
            int temp = dis[right-1]-dis[left-1];
            printf("%d
    ",min(temp,sum-temp));
        }
        return 0;
    }
    1065 A+B and C (64bit) (20分)

    Given three integers A, B and C in [−], you are supposed to tell whether A+B>C.

    Input Specification:

    The first line of the input gives the positive number of test cases, T (≤). Then T test cases follow, each consists of a single line containing three integers A, B and C, separated by single spaces.

    Output Specification:

    For each test case, output in one line Case #X: true if A+B>C, or Case #X: false otherwise, where X is the case number (starting from 1).

    Sample Input:

    3
    1 2 3
    2 3 4
    9223372036854775807 -9223372036854775808 0

    Sample Output:

    Case #1: false
    Case #2: true
    Case #3: false
    #include<cstdio>
    int main(){
        int T;
        scanf("%d",&T);
        int i=1;
        while(T--){
            long long A,B,C;
            scanf("%lld%lld%lld",&A,&B,&C);    
            long long res = A+B;
            bool flag;
            if(A > 0 && B>0 && res <0)
                flag = true;
            else if(A < 0 && B < 0 && res>=0)
                flag = false;
            else if(res > C)
                flag = true;
            else 
                flag = false;
            if(flag == true){
                printf("Case #%d: true
    ",i++);
            }else{
                printf("Case #%d: false
    ",i++);
            }
        }
        return 0;
    }
    1010 一元多项式求导 (25分)
     

    设计函数求一元多项式的导数。(注:xn​​(n为整数)的一阶导数为nxn1​​。)

    输入格式:

    以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过 1000 的整数)。数字间以空格分隔。

    输出格式:

    以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是 0,但是表示为 0 0

    输入样例:

    3 4 -5 2 6 1 -2 0

    输出样例:

    12 3 -10 1 6 0
    #include<cstdio>
    int main(){
        int a[1010]={0};
        int e,k,count=0;
        while(scanf("%d%d",&e,&k)!=EOF){
            a[k]=e;
        }
        a[0] = 0;
        for(int i=1;i<=1000;i++){
            a[i-1] = a[i]*i;
            a[i]= 0;
            if(a[i-1]!=0)
                count++;
        }
        if(count==0){
            printf("0 0");
        }else{
            for(int i=1000;i>=0;i--){
                if(a[i]!=0){
                    printf("%d %d",a[i],i);
                    count--;
                    if(count!=0)
                        printf(" ");
                }
            }
        }
        return 0;
    }
    1002 A+B for Polynomials (25分)
     

    This time, you are supposed to find A+B where A and B are two polynomials.

    Input Specification:

    Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:

    N1​​ aN1​​​​ N2​​ aN2​​​​ ... NK​​ aNK​​​​

    where K is the number of nonzero terms in the polynomial, Ni​​ and aNi​​​​ (,) are the exponents and coefficients, respectively. It is given that 1,0.

    Output Specification:

    For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.

    Sample Input:

    2 1 2.4 0 3.2
    2 2 1.5 1 0.5
    
     

    Sample Output:

    3 2 1.5 1 2.9 0 3.2

    #include<cstdio>
    int main(){
        int k;
        scanf("%d",&k);
        double p[1010]={};
        int n;
        double a;
        for(int i=0;i<k;i++){
            scanf("%d %lf",&n,&a);
            p[n] += a;
        }
        scanf("%d",&k);
        for(int i=0;i<k;i++){
            scanf("%d %lf",&n,&a);
            p[n] += a;
        }
        int count=0;
        for(int i=1000;i>=0;i--){
            if(p[i]!=0)
                count++;
        }
        printf("%d",count);
        for(int i=1000;i>=0;i--){
            if(p[i]!=0)
                printf(" %d %.1f",i,p[i]);
        }
        return 0;
    }
    1009 Product of Polynomials (25分)
     

    This time, you are supposed to find A×B where A and B are two polynomials.

    Input Specification:

    Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:

    N1​​ aN1​​​​ N2​​ aN2​​​​ ... NK​​ aNK​​​​

    where K is the number of nonzero terms in the polynomial, Ni​​ and aNi​​​​ (,) are the exponents and coefficients, respectively. It is given that 1, 0.

    Output Specification:

    For each test case you should output the product of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate up to 1 decimal place.

    Sample Input:

    2 1 2.4 0 3.2
    2 2 1.5 1 0.5

    Sample Output:

    3 3 3.6 2 6.0 1 1.6
    #include<cstdio>
    struct{
        int exp;
        double cof;
    }poly[1001];
    int main(){
        double ans[2001]={0.0};
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d %lf",&poly[i].exp,&poly[i].cof);
        }
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            int exp;
            double cof;
            scanf("%d %lf",&exp,&cof);
            for(int j=0;j<n;j++){
                ans[exp+poly[j].exp] += (cof*poly[j].cof);    
            }
        }
        int count=0;
        for(int i=0;i<2001;i++){
            if(ans[i]!=0.0)
                count++;
        }
        printf("%d",count);
        for(int i=2000;i>=0;i--){
            if(ans[i]!=0.0)
                printf(" %d %.1f",i,ans[i]);
        }
        return 0;
    }
     


  • 相关阅读:
    Red Hat Enterprise Linux 7.2下使用RPM包安装SQL Server vNext
    VS2015解决方案资源管理器空白,不显示内容
    ArcEngine调用FeatureToLine工具传参问题
    ArcEngine调用GP里的Merge工具传参问题
    ArcGIS GP服务的发布及调用
    利用 Chrome 原生工具进行网页长截图
    关于ueditor与arcgis js api同用会报错的问题
    关于ueditor使用说明
    bootstraptable为行中的按钮添加事件
    关于html与body的高度问题
  • 原文地址:https://www.cnblogs.com/coderying/p/12207776.html
Copyright © 2011-2022 走看看