1. 程式人生 > >2015年第六屆藍橋杯省賽A組(C/C++)

2015年第六屆藍橋杯省賽A組(C/C++)

部分轉載自:http://blog.csdn.net/summonlight/article/details/61920048

還有:https://zhidao.baidu.com/question/310414478.html

1. 方程整數解

方程: a^2 + b^2 + c^2 = 1000 
這個方程有整數解嗎?有:a,b,c=6,8,30 就是一組解。 
你能算出另一組合適的解嗎? 
請填寫該解中最小的數字。 

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

程式碼:

#include <cstdio>
#include <iostream>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;




int main(void)
{
    for(int i = 0; i < 1000; i++)
    {
        for(int j = 0; j < 1000; j++)
        {
            int k = 1000 - i * i - j * j;
            int kk = (int)(sqrt((double)(k)));
            if(k == kk * kk)
            {
                cout << i << "  " << j << "  " << kk << endl;
            }
        }
    }
    return 0;

}

正確答案:-30。

2. 星系炸彈

在X星系的廣袤空間中漂浮著許多X星人造“炸彈”,用來作為宇宙中的路標。 
每個炸彈都可以設定多少天之後爆炸。 
比如:阿爾法炸彈2015年1月1日放置,定時為15天,則它在2015年1月16日爆炸。 
有一個貝塔炸彈,2014年11月9日放置,定時為1000天,請你計算它爆炸的準確日期。 
請填寫該日期,格式為 yyyy-mm-dd 
即4位年份2位月份2位日期。比如: 
2015-02-19 
請嚴格按照格式書寫。不能出現其它文字或符號。

答案:2017-08-05

3. 奇妙的數字

小明發現了一個奇妙的數字。它的平方和立方正好把0~9的10個數字每個用且只用了一次。 
你能猜出這個數字是多少嗎? 
請填寫該數字,不要填寫任何多餘的內容。

程式碼:

#include <cstdio>

#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;


int book[11] = {};
bool check(long long num)
{
    long long two = num * num;
    long long three = num * num * num;
    while(two > 0)
    {
        book[two % 10]++;
        two = two / 10;
    }
    while(three)
    {
        book[three % 10]++;
        three = three / 10;
    }
    for(int i = 0; i <= 9; i++)
    {
        if(book[i] != 1) return false;
    }
    return true;
}
int main()
{
    for(long long num = 1; num < 9999; num++)
    {
        memset(book, 0, sizeof(book));
        if(check(num))
        {
            cout << num << endl;
            cout << num * num << endl;
            cout << num * num * num << endl;
            break;
        }
    }

}

答案:69

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     |
|                  |
|                  |
+------------------+

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

這個%*s的意思就是:*代表輸出的個數,s代表輸出的符號,所以答案是:

printf("%*s%s%*s", 5, "", buf, 5, "");

5是數出字串“abcd1234”左右都有五個空格

5. 九陣列分數

1,2,3…9 這九個數字組成一個分數,其值恰好為1/3,如何組法? 
下面的程式實現了該功能,請填寫劃線部分缺失的程式碼。

#include <stdio.h>

void test(int x[])
{
    int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
    int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];

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

void f(int x[], int k)
{
    int i,t;
    if(k>=9){
        test(x);
        return;
    }

    for(i=k; i<9; i++){
        {t=x[k]; x[k]=x[i]; x[i]=t;}
        f(x,k+1);
        _________________________________ // 填空處
    }
}

int main()
{
    int x[] = {1,2,3,4,5,6,7,8,9};
    f(x,0);  
    return 0;
}

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

我的答案:t = x[7];x[7] = x[8]; x[8] = t;

正確答案:t = x[k];x[k] = x[i]; x[i] = t;

這題我是把過程打出來後發現排列有點問題,不是全排列,少了一些排列,而有些排列又重複了,比如:

 

於是就想可能是排列時,第七個元素沒有和第八個元素對調導致的,其實是沒有復原,誒看來對全排列還是不太熟悉啊,參考一下:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html

還有:https://www.cnblogs.com/nowornever-L/p/6008954.html

6. 牌型種數

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

思路:首先,我們可以知道雖然是從52張牌中抽取13張牌,但是實際上應該是有13類牌,每類牌有四張,也就是往十三個位置放0~4中的一個數,問如何放能使這十三個位置的總和為13,這樣的放法有多少種,因此不能用排列組合的公式做,而只能用深度優先搜尋。

程式碼:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;


int arr[14] = {}, cnt = 0;


void dfs(int num[], int sum, int step)
{
    if(step > 13)
    {
        if(sum == 13)
        {
            cnt++;
        }
        return;
    }
    for(int j = 0; j <= 4; j++)
    {
        if(sum + j <= 13)
        {
            num[step] = j;
            //cout << "first  " << step << "  " << sum << "  " << j << endl;
            dfs(num, sum + j, step + 1);
            //cout << "second  " << step << "  " << sum << "  " << j << endl;
            num[step] = 0;
        }
        else break;
    }
}
int main()
{
    memset(arr, 0, sizeof(arr));
    dfs(arr, 0, 1);
    cout << cnt << endl;
    return 0;
}

答案:3598180

7. 手鍊樣式

小明有3顆紅珊瑚,4顆白珊瑚,5顆黃瑪瑙。 
他想用它們串成一圈作為手鍊,送給女朋友。 
現在小明想知道:如果考慮手鍊可以隨意轉動或翻轉,一共可以有多少不同的組合樣式呢? 請你提交該整數。不要填寫任何多餘的內容或說明性的文字。

思路:注意:手鍊可以隨意轉動或翻轉,也就是對於每組排列,都要以0~11為起點與之前的排列對比,看是否有重複,而且還要倒過來重複前面的操作。

程式碼:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;


int arr[16] = {}, cnt = 0;
struct node
{
    int num[12];
    node(int arr[])
    {
        for(int i = 0; i < 12; i++)
        {
            num[i] = arr[i];
        }
    }
    node(){}
};
vector<node>book;
bool check(int arr[])
{
    for(int i = 0; i < book.size(); i++)
    {
        for(int k = 0; k < 12; k++)
        {
            int j;
            bool flag = true;
            for(j = 0; j < 12; j++)
            {
                if(arr[j] != book[i].num[(k + j) % 12])
                {
                    flag = false;
                    break;
                }
            }
            if(flag)
            {
                return false;
            }
            flag = true;
            for(j = 0; j < 12; j++)
            {
                if(arr[11 - j] != book[i].num[(k+j)%12])
                {
                    flag = false;
                    break;
                }
            }
            if(flag) return false;
        }
    }
    book.push_back(arr);
    return true;
}
int main()
{
    for(int i = 0; i < 12; i++)
    {
        if(i < 3) arr[i] = 1;
        else if(i < 7) arr[i] = 2;
        else arr[i] = 3;
    }
    do{
        if(check(arr)) cnt++;
    }while(next_permutation(arr, arr + 12));
    cout << cnt << endl;
    return 0;
}

答案:1170

8. 飲料換購

樂羊羊飲料廠正在舉辦一次促銷優惠活動。樂羊羊C型飲料,憑3個瓶蓋可以再換一瓶C型飲料,並且可以一直迴圈下去(但不允許暫借或賒賬)。

請你計算一下,如果小明不浪費瓶蓋,儘量地參加活動,那麼,對於他初始買入的n瓶飲料,最後他一共能喝到多少瓶飲料。

輸入:一個整數n,表示開始購買的飲料數量(0 < n < 10000) 
輸出:一個整數,表示實際得到的飲料數

例如: 
使用者輸入: 
100 
程式應該輸出: 
149

使用者輸入: 
101 
程式應該輸出: 
151

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

請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。 
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。 
注意: main函式需要返回0 
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。 
注意: 所有依賴的函式必須明確地在原始檔中 #include , 不能通過工程設定而省略常用標頭檔案。 
提交時,注意選擇所期望的編譯器型別。

程式碼:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;




int main()
{
    int n, m;
    while(cin >> m)
    {
        n = m;
        int cnt = 0;
        while(n >= 3)
        {
            cnt += (n / 3);
            n = n / 3 + n % 3;
        }
        cout << cnt + m << endl;
    }
    return 0;

}

9. 壘骰子