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\n", a + b);//小數格式化輸出
        else if (c == 2) 
            printf("%.2lf\n", a - b);
        else if (c == 3) 
            printf("%.2lf\n", a * b);
        else 
            printf("%.2lf\n", 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\n");
        else
            printf("No\n");        
    }
    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\n", 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\n");
    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\n", 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\n"); 
        else
        { 
            int b[16]; 
            for (; n; n >>= 1)
            { 
                b[flag++] = n & 1; 
            } 
            for (; flag;) 
            printf("%d", b[--flag]); 
            printf("\n"); 
        } 
    } 
        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\n",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("\n");
    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\n", 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\n", 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"會在字符數組末尾加上一個'\n',所以數組開到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\n", 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");
    }
} 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM