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;
}