2015年第六屆藍橋杯試題(C/C++本科B組)
1
有些人很迷信數字,比如帶“4”的數字,認為和“死”諧音,就覺得不吉利。雖然這些說法純屬無稽之談,但有時還要迎合大眾的需求。某抽獎活動的獎券號碼是5位數(10-99),要求其中不要出現帶“4”的號碼,主辦單位請你計算一下,如果任何兩張獎券不重號,最多可發出獎券多少張。
請提交該數字(一個整數),不要寫任何多餘的內容或說明性文字。
答案:第一位不取0和4,剩下四位不取4, 8*9*9*9*9
2
星系炸彈
在X星系的廣袤空間中漂浮著許多X星人造“炸彈”,用來作為宇宙中的路標。每個炸彈都可以設定多少天之後爆炸。比如:阿爾法炸彈2015年1月1日放置,定時為15天,則它在2015年1月16
請填寫該日期,格式為 yyyy-mm-dd即4位年份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 .....
我們的問題是:已知了兩個樓號m和n,需要求出它們之間的最短移動距離(不能斜線方向移動)
輸入為3個整數w m n,空格分開,都在1到10範圍內
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;
}