1. 程式人生 > >2015年第六屆藍橋杯試題(C/C++本科B組)

2015年第六屆藍橋杯試題(C/C++本科B組)

1

有些人很迷信數字,比如帶“4”的數字,認為和諧音,就覺得不吉利。雖然這些說法純屬無稽之談,但有時還要迎合大眾的需求。某抽獎活動的獎券號碼是5位數(10-99),要求其中不要出現帶“4”的號碼,主辦單位請你計算一下,如果任何兩張獎券不重號,最多可發出獎券多少張。

請提交該數字(一個整數),不要寫任何多餘的內容或說明性文字。

答案:第一位不取0和4,剩下四位不取4,        8*9*9*9*9

2

星系炸彈

X星系的廣袤空間中漂浮著許多X星人造炸彈,用來作為宇宙中的路標。每個炸彈都可以設定多少天之後爆炸。比如:阿爾法炸彈201511日放置,定時為15天,則它在2015116

日爆炸。有一個貝塔炸彈,2014119日放置,定時為1000天,請你計算它爆炸的準確日期。

請填寫該日期,格式為 yyyy-mm-dd4位年份2位月份2位日期。比如:2015-02-19
請嚴格按照格式書寫。不能出現其它文字或符號。

答案:2017-08-05

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;

int mon[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

bool isleap(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        return true;
    return false;
}

int main()
{
    int year = 2014;
    int month,day;
    int sum = 1000 - 52;//到這一年年底的時候剩餘的時間
    int sum1;
    while(true)
    {
        if(isleap(year+1))
        {
            sum1 = 366;
        }
        else
        {
            sum1 = 365;
        }
        if(sum < sum1)
        {
            year++;
            break;
        }
        else
        {
            year++;
            sum -= sum1;
        }
    }
    if(isleap(year))
    {
        mon[2]++;
    }
    for(int i=1; i<=12; i++)
    {
        if(sum > mon[i])
        {
            sum -= mon[i];
        }
        else
        {
            month = i;
            break;
        }
    }
    day = sum;
    printf("%d %d %d\n",year,month,day);
    return 0;
}

3

三羊獻瑞

觀察下面的加法算式:


+  

-
 

(如果有對齊問題,可以參看【圖1.jpg)

其中,相同的漢字代表相同的數字,不同的漢字代表不同的數字。

請你填寫三羊獻瑞所代表的4位數字(答案唯一),不要填寫任何多餘內容。

答案:1085
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;

int a[10];
int visit[10] = {0};

void dfs(int cur)
{
    if(cur == 8)
    {
        int sum = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
        int sum1 = a[4] * 1000 + a[5] * 100 + a[6] * 10 + a[1];
        int sum2 = a[4] * 10000 + a[5] * 1000 + a[2] * 100 + a[1] * 10 + a[7];
        if(sum + sum1 == sum2)
        {
            printf("%d %d %d\n",sum,sum1,sum2);
        }
        return;
    }
    for(int i=0; i<10; i++)
    {
        if(i == 0 && cur == 0)
            continue;
        if(i == 0 && cur == 4)
            continue;
        if(!visit[i])
        {
            visit[i] = 1;
            a[cur] = i;
            dfs(cur+1);
            visit[i] = 0;
        }
    }
}

int main()
{
    dfs(0);
    return 0;
}

4


格子中輸出

StringInGrid函式會在一個指定大小的格子中列印指定的字串。

要求字串在水平、垂直兩個方向上都居中。

如果字串太長,就截斷。

如果不能恰好居中,可以稍稍偏左或者偏上一點。

下面的程式實現這個邏輯,請填寫劃線部分缺少的程式碼。

#include <stdio.h>

#include <string.h>

void StringInGrid(int width, int height, const char* s)

{

       int i,k;

       char buf[1000];

       strcpy(buf, s);

       if(strlen(s)>width-2)buf[width-2]=0;

       printf("+");

       for(i=0;i<width-2;i++)printf("-");

       printf("+\n");

       for(k=1;k<(height-1)/2;k++){

              printf("|");

              for(i=0;i<width-2;i++)printf(" ");

              printf("|\n");

       }

       printf("|");

       printf("%*s%s%*s",_____________________________________________);  //填空

       printf("|\n");

       for(k=(height-1)/2+1;k<height-1; k++){

              printf("|");

              for(i=0;i<width-2;i++)printf(" ");

              printf("|\n");

       }    

       printf("+");

       for(i=0;i<width-2;i++)printf("-");

       printf("+\n");

}

int main()

{

       StringInGrid(20,6,"abcd1234");

       return 0;

}

對於題目中資料,應該輸出:

+------------------+

|                  |

|     abcd1234     |

|                  |

|                  |

+------------------+


(如果出現對齊問題,參看【圖1.jpg】)

注意:只填寫缺少的內容,不要書寫任何題面已有程式碼或說明性文字。

答案:(width-strlen(s)-2)/2,"",s,(width-strlen(s)-1)/2,""(什麼鬼,完全看不懂啊)


5

九陣列分數

1,2,3...9 這九個數字組成一個分數,其值恰好為1/3,如何組法?

下面的程式實現了該功能,請填寫劃線部分缺失的程式碼。

 1 #include <stdio.h>

 2

 3void test(int x[])

 4 {

 5int a = x[0] *1 + x[1] *100 + x[2] *10 + x[3];

 6int b = x[4] *10 + x[5] *1 + x[6] *100 + x[7] *10 + x[8];

 7

 8if (a *3 == b) printf("%d / %d\n", a, b);

 9 }

10

11void f(int x[],int k)

12 {

13int i, t;

14if (k >=9)

15     {

16         test(x);

17return;

18     }

19

20for (i = k; i<9; i++)

21     {

22         {t = x[k];x[k] = x[i]; x[i] = t; }

23         f(x, k +1);

24        _____________________________________________//填空處

25     }

26 }

27

28int main()

29 {

30int x[] = {1,2,3,4,5,6,7,8,9 };

31     f(x,0);

32return0;

33 }

注意:只填寫缺少的內容,不要書寫任何題面已有程式碼或說明性文字。

答案:簡單回溯,就是全排列程式碼,把順序倒過來就行

t = x[k];x[k] = x[i]; x[i] = t; 

還以為寫程式碼了,寫了一遍,貼上來吧

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;

int a[10];
int visit[10] = {0};

void dfs(int cur)
{
    if(cur == 9)
    {
        int sum = a[0] * 10000 + a[1] * 1000 + a[2] * 100 + a[3] * 10 + a[4];
        int sum1 = a[5] * 1000 + a[6] * 100 + a[7] * 10 + a[8];
        if(sum % sum1 == 0 && sum / sum1 == 3)
        {
            printf("%d  %d\n",sum,sum1);
        }
        return;
    }
    for(int i=0; i<10; i++)
    {
        if(i == 0 && cur == 0)
            continue;
        if(i == 0 && cur == 4)
            continue;
        if(!visit[i])
        {
            visit[i] = 1;
            a[cur] = i;
            dfs(cur+1);
            visit[i] = 0;
        }
    }
}

int main()
{
    dfs(0);
    return 0;
}
6

加法變乘法

我們都知道:1+2+3+ ... + 49 = 1225
現在要求你把其中兩個不相鄰的加號變成乘號,使得結果為2015

比如:
1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015
就是符合要求的答案。

請你尋找另外一個可能的答案,並把位置靠前的那個乘號左邊的數字提交(對於示例,就是提交10)。

注意:需要你提交的是一個整數,不要填寫任何多餘的內容。

答案:16

列舉乘號的位置即可

49個數中間有48個符號

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;


int main()
{
    for(int i=1; i<=46; i++)
    {
        for(int j=i+2; j<=48; j++)
        {
            int sum = 0;
            for(int k=1; k<i; k++)
            {
                sum += k;
            }
            sum += i * (i+1);
            for(int k=i+2; k<j; k++)
            {
                sum += k;
            }
            sum += j * (j+1);
            for(int k=j+2; k<=49; k++)
            {
                sum += k;
            }
            if(sum == 2015)
            {
                printf("%d  %d\n",i,j);
            }
        }
    }
}

7

小明被劫持到X賭城,被迫與其他3人玩牌。一副撲克牌(去掉大小王牌,共52張),均勻發給4個人,每個人13張。這時,小明腦子裡突然冒出一個問題:如果不考慮花色,只考慮點數,也不考慮自己得到的牌的先後順序,自己手裡能拿到的初始牌型組合一共有多少種呢?

請填寫該整數,不要填寫任何多餘的內容或說明文字。

答案:3598180(每種牌的個數是0,1,2,3,4)列舉一下即可

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;

int ans = 0;

void dfs(int cur,int sum)
{
    if(sum > 13)
    {
        return;
    }
    if(cur == 13)
    {
        if(sum == 13)
        {
            ans++;
        }
        return;
    }
    for(int i=0; i<=4; i++)
    {
        dfs(cur+1,sum+i);
    }
}

int main()
{
    dfs(0,0);
    printf("%d\n",ans);
    return 0;
}


8

X星球居民小區的樓房全是一樣的,並且按矩陣樣式排列。其樓房的編號為1,2,3...
當排滿一行時,從下一行相鄰的樓往反方向排號。比如:當小區排號寬度為6時,開始情形如下:

1   2   3   4 5 6
12 11 10  9 8 7
13 14 15 .....

我們的問題是:已知了兩個樓號mn,需要求出它們之間的最短移動距離(不能斜線方向移動)

輸入為3個整數w m n,空格分開,都在110範圍內
w
為排號寬度,m,n為待計算的樓號。要求輸出一個整數,表示m n兩樓間最短移動距離。

例如:使用者輸入:
6 8 2
則,程式應該輸出:
4

再例如:使用者輸入:
4 7 20
則,程式應該輸出:
5

資源約定:峰值記憶體消耗 < 256M
CPU
消耗 < 1ms

請嚴格按要求輸出,不要畫蛇添足地列印類似:請您輸入...”的多餘內容。

所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。

注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>不能通過工程設定而省略常用標頭檔案。

提交時,注意選擇所期望的編譯器型別。

答案:求每個數的座標,橫縱座標減一下取絕對值加起來就行

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;

int main()
{
    int w,m,n;
    while(scanf("%d%d%d",&w,&m,&n) != EOF)
    {
        int a = m / w;
        if(m % w == 0)//每個數的橫縱座標都是從0開始,整除橫座標減1
            a -= 1;
        int b = n / w;
        if(n % w== 0)
            b -= 1;
        int c,d;
        if(a % 2 == 1)
        {
            c = abs(m - w*(a+1));
        }
        else
        {
            c = m - (w * a + 1);
        }
        if(b % 2 == 1)
        {
            d = abs(n-w*(b+1));
        }
        else
        {
            d = n - (w * b  + 1);
        }
        int sum = abs(a-b) + abs(c-d);
        printf("%d\n",sum);
    }
    return 0;
}