• SWPUACM招新赛


    SWPUACM招新赛

    A.简单的计算器

    题目描述

    whitabbit最近在给他的小表弟辅导加减乘除运算,但是whitabbit的数学很差,想找一个计算器来帮他做一下,请问你能帮帮他吗

    输入

    第一行包含一个整数T(1<=T<=5)
    接下来每行包含三个整数a,b,c(1<=a,b<=1000,1<=c<=4)
    当c为1时,请输出a+b的结果
    当c为2时,请输出a-b的结果
    当c为3时,请输出a*b的结果
    当c为4时,请输出a/b的结果
    以上所有计算出的结果都保留两位小数

    输出

    输出每组数据对应的值

    样例输入

    4

    3 2 1

    3 2 2

    3 2 3

    3 2 4

    样例输出

    5.00

    1.00

    6.00

    1.50

    思路:因为a和b会涉及到除法,虽然题目说a和b都是整数,但是整数的除法会让精度丢失,所以我们定义double类型的a和b(当然强制转换也行)

    详情看下面这一篇博客:

    传送门

    code:

    #include <stdio.h>
    int main() {
        int n;
        scanf("%d", &n);//T组输入
        while (n--) 
        {
            double a, b;
            int c;
            scanf("%lf%lf%d", &a, &b, &c);
            if (c == 1) 
                printf("%.2lf
    ", a + b);//小数格式化输出
            else if (c == 2) 
                printf("%.2lf
    ", a - b);
            else if (c == 3) 
                printf("%.2lf
    ", a * b);
            else 
                printf("%.2lf
    ", a / b);
        }
        return 0;
    }

    B.三角形判断

    题目描述

    给你三根长度为a,b,c的木棍,判断是否能组成三角形 whitabbit的良心签到题,拼手速辣ヾ(≧▽≦*)o 

    输入

    第一行包含一个整数T(1<=T<=100000)
    接下来T行每行包含三个整数a,b,c(1<=a,b,c<=1000) 

    输出

    如果能组成三角形,则输出Yes
    反之,输出No 

    样例输入

    3

    3 4 5

    6 8 10

    2 2 4 

     

    样例输出

    Yes

    Yes

    No

    思路:初中数学,地球人都知道只要满足两边之和大于第三边就行,但是请注意对于每一个边都要判断。

    code:

    #include <stdio.h>
    int main()
    {
        int t,a,b,c;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d %d",&a,&b,&c);
            if(c+a>b&&b+a>c&&b+c>a)
                printf("Yes
    ");
            else
                printf("No
    ");        
        }
        return 0;
    }

    C.秋天的第1,2,3,4,5,6...杯奶茶

    题目描述

    whitabbit准备给雷学姐买杯奶茶,但是雷学姐说自己要喝1,2,3,4,5,6,7,8,9...杯奶茶,那 么问题来了,请问1+2+3+...+n等于多少? 

    输入

    第一行包含一个整数T(1<=T<=100000)
    接下来T行每行包含一个整数n(1<=n<=10000) 

    输出

    对于每个整数n,输入对应的答案

    样例输入

    5

    1

    2

    3

    4

    5

    样例输出

    1

    3

    6

    10

    15

    思路:等差数列求和公式:sum=n*(n+1)/2,但是这一题注意使用int,long long 会出现wa的情况(原因未知)

    #include <stdio.h>
    
    int main() {
        int n;
        scanf("%d", &n);
        while (n--) {
            int num;
            scanf("%d", &num);
            printf("%d
    ", num * (num + 1) / 2);
        }
        return 0;
    }

    D.mangata学长的求助

    题目描述

    miyou学长某日夜观天象,隐约从浩瀚星河中看出几串奇怪的数字和字母,说不定这是外星人向地球人发出的信号,miyou学长看出其中机密后就向mangata学长分享,然而mangata学长看不懂其中奥秘,遭到了miyou学长的无情嘲讽,mangata学长百般无奈,只能向你寻求帮助,你能帮他解难吗?答案只有一个,输出即可。
    问:19141115输出什么

    输入

    本题无输入

    输出

    你只需要打印19141115对应的英语单词即可,换句话说这道题你只需要printf一个单词就正确了,很简单哦

     

    样例输入

    4157

    3120

    样例输出

    dog

    cat

    思路:思维题,不考代码,数字为字母序号,两位数会有两种情况,但是数字不大,也知道是个英文单词

    简单推理就知道19141115是:

    19 14 1 11 5
     s   n   a  k  e

    code:

    #include<stdio.h>
    int main()
    {
        printf("snake
    ");
        return 0;
    }

    E.进制转换

    题目描述

    雷学姐最近在学计算机组成原理和Linux编程,但是使用Linux指令编译程序的过程中,c语言会转化 成汇编语言再进行链接。

    这其中涉及到了二进制转换的问题,雷学姐比较笨,你可以帮帮她吗?

    输入

    第一行包含一个整数T(1<=T<=200)
    给你一个整数n把它转化为二进制数并输出(0<=n<=100) 

    输出

    对应每个输入的十进制数,输出其二进制数

    样例输入

    5

    0

    2

    3

    4

    5

    样例输出

    0

    10

    11

    100

    101

    题意:题目给出T组数据,接下来T行,每行一个十进制整数n,我们需要将其化为二进制并输 出。看到十进制转二进制,第一个反应出来的做法肯定是短除法。简单题,直接贴代码。 

    code:  C++:

    #include<bits/stdc++.h> 
    using namespace std; 
    int main() 
    { 
        ios ::sync_with_stdio(0); 
        cin.tie(0); 
        cout.tie(0); 
        int T; 
        cin >> T; 
        while (T--) 
        { 
            int n; 
            cin >> n; 
            int sum = 0; 
            int flag = 1; 
            while (n > 0) 
            { 
                int temp = n % 2; 
                sum += temp * flag; 
                flag *= 10; n /= 2; 
            } 
            cout << sum << endl; 
            } return 0; 
    } 

    code  C:

    #include<stdio.h> 
    int main() 
    { 
        int t; 
        scanf("%d", &t); 
        int n; 
        while (t--) 
        { 
            scanf("%d", &n); 
            int sum = 0; 
            int flag = 1; while 
            (n > 0) 
            { 
                int temp = n % 2; 
                sum += temp * flag; 
                flag *= 10; n /= 2; 
            } 
            printf("%d
    ", sum); 
        }
            return 0;
    }

    当然如果你学习过二进制的话,这道题有更好的基于二进制的解法。代码如下:

    #include <bits/stdc++.h> 
    using namespace std; 
    int main() 
    { 
        ios ::sync_with_stdio(0); 
        cin.tie(0); cout.tie(0); 
        int T; 
        cin >> T; 
        while (T--) 
        { 
            int n; 
            int flag = 0; 
            cin >> n; 
            if (n == 0)
            cout << "0" << endl; 
            else 
            { 
                int b[16]; 
                for (; n; n >>= 1) 
                { 
                    b[flag++] = n & 1; 
                } 
                    for (; flag;) 
                    cout << b[--flag]; 
                    cout << endl; 
            } 
        } 
        return 0;
    } 

    C:

    #include <stdio.h> 
    int main() 
    { 
        int t; 
        scanf("%d", &t); 
        while (t--) 
        { 
            int n;
            int flag = 0; 
            scanf("%d", &n); 
            if (n == 0) 
            printf("0
    "); 
            else
            { 
                int b[16]; 
                for (; n; n >>= 1)
                { 
                    b[flag++] = n & 1; 
                } 
                for (; flag;) 
                printf("%d", b[--flag]); 
                printf("
    "); 
            } 
        } 
            return 0; 
    } 

    By the way:这题是简单版,进阶版是多组输入,每行一个十进制数N和一个整数R,要求你将十进制数 N转换成R进制数并输出。 有兴趣的可以去拓展一下,题目链接:

    传送门

    F.机器人大赛

    题目描述

    Stefan准备参加机器人大赛,并且准备好了他的坐标机器人。假设机器人一开始都在原点上(0,0)并且面朝y正半轴。规定1,2,3,4,5...分别对应机器人的正前方、左方、后方,右方,正前方...现在给它发送坐标指令如(1,1),它就会向正前方方向移动一格。如果再给机器人发送坐标指令如(4,1),它就会向右方向移动一格并且此时面朝x正半轴。如果再给机器人发送坐标指令如(1,1),它就会向正前方方向移动一格。最后机器人就会走到坐标(2,1)上。

    那么问题来了,在Stefan给机器人发送了一系列的指令之后,机器人会在哪个坐标停下呢?

    输入

    单组输入
    第一行输入一个数n (1<=n<=100000)
    接下来的n+1行输入m,k  (m表示移动方向 1<=m<=100000)  (k表示移动步数 1<=k<=10000000)

    输出

    输入两个数x,y 表示机器人最后停下来的坐标

    样例输入

    3

    1 1

    3 1

    1 1

    样例输出

    0 -1

    思路:很明显,地球人都知道这是一道模拟题,一共有十六种情况,因为朝向(前后左右)是四个方向,每个方向都有四个选择,往前、往左、往后、往右,注意一下输入的操作不只是1-5,

    后面有省略号的,也就是说你每次要对操作取余,然后分别对应四种情况就行,等于零就是往右(就是整除嘛)。注意机器人每次行动后与要及时更新当前朝向,并且注意本题要用long long

    code:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long//让long long 用ll代替
    ll m,k,x,y,n;
    int face;
    int main(){
        scanf("%lld",&n);
            x=0,y=0;
        for(int i=0;i<n;++i){
            scanf("%lld %lld",&m,&k);
            if(face==0){//face表示的是四个朝向,这是朝前
            if(m%4==1)//往前
                y+=k;
            else if(m%4==2)//往左
                x-=k,face=3;
            else if(m%4==3)//往后
                y-=k,face=2;
            else if(m%4==0)//往右
                x+=k,face=1;
            }
            else if(face==1){//朝右
                if(m%4==1)
                x+=k;
                else if(m%4==2)
                y+=k,face=0;
                else if(m%4==3)
                x-=k,face=3;
                else if(m%4==0)
                y-=k,face=2;
            }
            else if(face==2){//朝后
                if(m%4==1)
                y-=k;
                else if(m%4==2)
                x+=k,face=1;
                else if(m%4==3)
                y+=k,face=0;
                else if(m%4==0)
                x-=k,face=3;
            }
            else if(face==3){//朝左
                if(m%4==1)
                x-=k;
                else if(m%4==2)
                y-=k,face=2;
                else if(m%4==3)
                x+=k,face=1;
                else if(m%4==0)
                y+=k,face=0;
            }
        }
        printf("%lld %lld
    ",x,y);
    }

    G.顺时针矩阵

    题目描述

    输入一个n*m(0<=n,m<=100)的矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

    输入

    单组输入
    第一行有两个数n,m,表示矩阵有n行m列,
    接下来的n行,每行有m个数字。
    数据保证每个数字大小都在int范围内。

    输出

    输出一行数字,代表矩阵从外向里顺时针的顺序。

    样例输入

    3 4

    1 2 3 4

    5 6 7 8

    9 10 11 12

    样例输出

    1 2 3 4 8 12 11 10 9 5 6 7

    先把矩阵用一个二维数组存起来,然后从外圈到内圈遍历,先输出横行然后竖行,直到每个位置都输出就结束

    code:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,m;
    int mp[105][105];
    int vis[105][105];
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i< n;++i){
            for(int j=0;j<m;++j){
                scanf("%d",&mp[i][j]);//存二维矩阵
            }
        }
        int len=0;
        int i=0,j=0;
        while(len<n*m){//判断是否全部遍历
            while(j<m){//输出上面的横行
                if(vis[i][j])
                break;
                vis[i][j]=1;//标记访问过
                len++;
                printf("%d ",mp[i][j++]);
            }
            j--;
            i++;
            while(i<n){//输出右边的竖行
                if(vis[i][j])
                break;
                vis[i][j]=1;
                len++;
                printf("%d ",mp[i++][j]);
            }
            i--;
            j--;
            while(j>=0){//输出下面的横行
                if(vis[i][j])
                break;
                vis[i][j]=1;
                len++;
                printf("%d ",mp[i][j--]);
            }
            j++;
            i--;
            while(i>=0){//输出左边的竖行
                if(vis[i][j])
                break;
                vis[i][j]=1;
                len++;
                printf("%d ",mp[i--][j]);
            }
            i++;
            j++;
        }
        printf("
    ");
        return 0;
    }

     

     

    H.善良的洋芋

    题目描述

    善良的洋芋要去参加ACM招新赛了,在途径龙井湖的路上遇见了一只饥肠辘辘的小猫,
    小猫祈求洋芋给它吃的,可是洋芋最近囊中羞涩,但是善良的洋芋不忍心小猫挨饿,
    于是洋芋打算和小猫玩一个游戏来决定是否给小猫买吃的,你能尽快帮助小猫解决这个问题吗?
    龙井湖的旁边有n(n <= 24)根树枝,可以用这些树枝拼数字。0 ~ 9 的拼法如下图所示:



    假如小猫有14根树枝,则可以拼两个等式 0 + 1 = 1 和 1 + 0 = 0

    注意:1.加号和等号各自需要两个树枝

    2.如果A不等于B 则A + B = C 和 B + A = C 视为不同等式

    3.所有树枝必须全部用上

    输入

    第一行包含一个整数T(1<=T<=100)
    接下来T行每行包含一个数n代表树枝数 (n <= 24)

    输出

    输出可以拼出的等式的数目

     

    样例输入

    2

    14

    1

    样例输出

    2

    0

     

    思路:最多24根树枝,等号和加号总共用掉4个,数字1需要的树枝数目最小。总共可以拼出10个1, 所以a b c中最大的只能小于1111;然后枚举即可。

    但是不用枚举c, 因为c可以直接通过a + b 算出来,时间复杂度从n^3 降到 n^2

    code:

    #include <cstdio>
    #include <cstring>
    //get函数计算需要火柴棍的总数
    int get(int x) {
        int num = 0;
        int f[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
        // 如果x大于9
        while(x / 10 != 0) {
            num += f[x % 10];
            x /= 10; // 去掉x末尾数字123 -> 12
        }
        num += f[x];
        return num;
    }
    int main() {
        int a, b, c, n, sum;
        int t;
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            sum = 0;
            for(int a = 0; a <= 1111; a++) {
                for(int b = 0; b <= 1111; b++) {
                    c = a + b;
                    if(get(a) + get(b) + get(c) == n - 4) {
                        sum++;
                    }
                }
            }
            printf("%d
    ", sum);
        }
    
        return 0;
    }

    I.whitabbit的三子棋

    题目描述

    whitabbit有一个棋盘,长为m,宽为n,他有三个棋子,可以在棋盘任意位置摆放,当这三个棋子横、竖、斜连在一起时,whitabbit就能够获得胜利,但是whitabbit想知道他有多少种方法获胜,whitabbit数学很差,所以请你来帮他算一下

    输入

    第一行包含一个整数T(1<=T<=100)
    接下来T行每行包含两个整数m,n(1<=m,n<=10000)
    ps:本题请使用long long和%lld去替换int和%d

    输出

    输入whitabbit获胜方法数

    样例输入

    5

    1 1

    1 2

    1 3

    2 3

    3 3

    样例输出

    0

    0

    1

    2

    8

    思路:根据获胜规律能推一个公式,感兴趣可以推一下,我直接放代码

    code:

    #include<stdio.h>
    #include<math.h>
    
    int min(int a,int b){
        if(a>b){
            return b;
        }else{
            return a;
        }
    }
    
    int main() {
        long long m, n;
        int t;
        scanf("%d",&t);
        while (t--) {
            scanf("%lld%lld",&m,&n);
            long long ans = 0;
            if (n >= 3)
                ans += m * (n - 2);
            if (m >= 3)
                ans += n * (m - 2);
            if (m >= 3 && n >= 3)
                ans += 2 * ((min(m, n) - 2) * (min(m, n) - 2) + abs(m - n) * (min(m, n) - 2));
            printf("%lld
    ", ans);
        }
        return 0;
    }

    J.Dawntwilight的日期

    题目描述

    Dawntwilight不会出题,所以这只是一道简单的水题。给你两个日期,请你判断这两个日期之间有多少个整周(即,从周一到周日,不满足这个条件的不算)。

    输入

    日期的形式为yyyy-mm-dd(如:2020-10-02),两个日期之间以空格隔开。数据保证合法。满足第二个日期一定在第一个日期之后,1945<=yyyy<=2020。

    输出

    输出一行,只有一个数字,代表两个日期之间的整周的个数。

    样例输入

    1984-08-15 2019-11-12

    样例输出

    1838

    思路:见代码,这道题由于数据比较水,所以有人水过去了下面是正确的做法

    code:

    #include <bits/stdc++.h>
    using namespace std;
    //把long long 定义为ll,在代码中定义变量时,ll 等效与long long
    typedef long long ll;
    //每月的天数
    int dd[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
    //判断是不是闰年
    bool check(int y){
        //判断闰年
        if((y%4==0&&y%100!=0)||y%400==0)
            return true;
        return false;
    }
    //计算该日期当年已经过了多少天
    int DayAgo(int y, int m, int d){
        int cnt = 0;
        //如果是闰年并且月份大于2就加一天
        if(check(y)&&m>2)
            cnt++;
        //加上m月之前的月份天数
        for(int i=0;i<m-1;i++)
            cnt += dd[i];
        //加上m月的天数
        cnt += d;
        return cnt;
    }
    //计算两个日期之间的天数
    int MinusDay(char s1[11], char s2[11]){
        int y1, y2, m1, m2, d1, d2;
        //将字符数组转化为整型数字
        y1 = ((s1[0]-'0')*1000 + (s1[1]-'0')*100 + (s1[2]-'0')*10 + s1[3]-'0');
        y2 = ((s2[0]-'0')*1000 + (s2[1]-'0')*100 + (s2[2]-'0')*10 + s2[3]-'0');
        m1 = ((s1[5]-'0')*10 + s1[6]-'0');
        m2 = ((s2[5]-'0')*10 + s2[6]-'0');
        d1 = ((s1[8]-'0')*10 + s1[9]-'0');
        d2 = ((s2[8]-'0')*10 + s2[9]-'0');
        //保存两个日期之间的天数
        ll summ = 0;
        //把第一个个日期所在的年份也当做整年,计算之间的天数
        summ += (y2 - y1) / 4 * (365*3+366);
        for(int i=1;i<=(y2-y1)%4;i++){
            if(check(y2-i))
                summ += 366;
            else
                summ += 365;
        }
        //减去第一个日期已经过了的天数,加上第二个日期已经过去的天数
        summ -= DayAgo(y1, m1, d1);
        summ += DayAgo(y2, m2, d2);
        return summ;
    }
    int main(){
        //因为日期有10个字符,用"%s"会在字符数组末尾加上一个'
    ',所以数组开到11
        char s1[11], s2[11];
        scanf("%s %s", s1, s2);
        //计算两个日期之间间隔的天数
        int sum = MinusDay(s1, s2);
        //计算两个日期当天是周几
        //利用一个已知是周几的日期,比如"2020-10-02"是周五来计算输入的日期是周几
        char s[11] = "2020-10-02";
        //这两个变量存的是输入的日期的星期数
        int ct1 = (MinusDay(s1, s) + 4) % 7;
        int ct2 = (MinusDay(s2, s) + 4) % 7;
        //处理一下数据,保证不出现负数,处理过程用是三目运算
        ct1 = ct1 > 0 ? ct1 : -ct1;
        ct2 = ct2 > 0 ? ct2 : -ct2;
        //减去不在整周的天数
        //ct1和ct2加1之后才是正确的星期数
        sum -= 7 - (ct1 + 1) + ct2 + 1;
        //保证结果不为负
        if (sum < 0)
            sum = 0;
        //计算整周数
        sum /= 7;
        printf("%d
    ", sum);
        return 0;
    }

    K.节约的Mangata

    题目描述

    In the past, Mangata had a girlfriend. After he went to university, Mangata and his girlfriend were not in the same school or even in the same city, so Mangata would visit her every month (because Mangata's money is not enough to visit every week) Since Mangata’s monthly living expenses are limited, Mangata must plan his living expenses reasonably, otherwise he will not be able to go to his girlfriend, because every time he visits his girlfriend Mangata will spend half of his living expenses , plus The girlfriend of Mangata likes to eat Take-out food very much, so Mangata also orders takeaway for his girlfriend every month. The witty Mangata has a membership card. For every RMB m spent on the membership card, a discount of RMB m/2 will be given.(rounded down) Since Mangata is stupid and doesn't know if half of the living expenses are enough, so he found you who is about to enter ACM, I hope you can tell him if it is enough.
    热心的Mangata的翻译:
    在以前Mangata是有女朋友的,上了大学后,Mangata和他的女朋友不在同一个学校甚至不在同一个城市,所以Mangata每个月都会去看她(因为Mangata的钱不够每周去看),由于Mangata每个月的生活费有限,Mangata必须合理规划自己的生活费,不然就去不了他女朋友那里了,因为每次去看女朋友Mangata都会花费生活费的一半(向下取整,例如:5/2=2.5,向下取整则为2),再加上Mangata的女朋友很喜欢吃夜宵,所以Mangata每个月还要给他的女朋友点外卖,机智的Mangata办了一张会员卡,会员卡每消费m元,将会优惠m/2元,由于Mangata很笨不知道一半的生活费够不够,所以他找到了即将进入ACM的你,希望你能告诉他够不够花。

    输入

    T组输入,第1行输入一个表示数据的组数(1<=T<10005) 
    第二行输入一个n表示Mangata每个月的生活费。(n为正整数)
    第三行输入一个k表示Mangata女朋友每个月要吃多少次外卖。 (m为正整数)
    第四行到k+4行输入每次点外卖的费用。
    所有数据均不大于1000005

    输出

    如果Mangata的生活费够用,那么请输出MangataYES!,否则输出QAQ

    样例输入

    1

    10

    3

    2

    2

    2

    样例输出

    MangataYES!

    思路:因为Mangata办理了会员卡,所以每次夜宵费用会减半,然后我们用一个变量sum存储每次宵夜的花费,用另一个变量dis存储宵夜的折扣(当然折扣可能会有0,eg:花费为1的时候)

    由于整数运算的除法就是向下取整的,所以我们不用管题目的向下取整(这就是幌子而已hhh),接下来我说说很多人wa50%,那是因为宵夜的折扣,不能把每次的消费加起来,然后除二,因为折扣可能单次为0

    一道很简单的题,不知道你们为什么没想到=_=

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    //这些奇奇怪怪的头文件是C++的,可以不用管,C写stdio.h就行
    int n,mo,t,sum,dis;
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&t);
            dis=sum=0;
            for(int j=1;j<=t;++j)
            {
                scanf("%d",&mo);//输入宵夜的价钱
                dis+=mo/2;//打折的优惠,注意这里,很多人都是wa50%,因为宵夜的优惠可能是0
                sum+=mo;//这是每次夜宵的价钱
            }
            n-=2*(sum-dis);
            if(n>=0)
            puts("MangataYES!");//通过这个输出字符串语句会自动带一个换行符
            else
            puts("QAQ");
        }
    } 

     

  • 相关阅读:
    LeetCode
    LeetCode
    static,final,包,访问修饰符,内部类
    抽象类和抽象方法接口和多态
    抽象类和抽象方法
    memcache的使用、版本使用和相关配置
    apache mysql无法启动解决办法
    thinkphp实现文件的下载
    xampp 出现403 无法访问问题(已解决)
    Thinkphp使用phpexcel导入文件并写入数据库
  • 原文地址:https://www.cnblogs.com/Mangata/p/13837285.html
Copyright © 2020-2023  润新知