第七屆藍橋杯C/C++ A組省賽題解
阿新 • • 發佈:2018-12-22
1.網友年齡
某君新認識一網友。當問及年齡時,他的網友說:
“我的年齡是個2位數,我比兒子大27歲,
如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡”
請你計算:網友的年齡一共有多少種可能情況?
提示:30歲就是其中一種可能哦.
請填寫表示可能情況的種數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
答案:7
程式碼:
#include <iostream> using namespace std; int main() { int ans=0; for(int i=0;i<=9; i++) for(int j=0; j<=9;j++) if( (i*10+j)-(j*10+i)==27 ) ans++; cout<<ans; return 0; }
2.生日蠟燭
某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。現在算起來,他一共吹熄了236根蠟燭。
請問,他從多少歲開始過生日party的?
請填寫他開始過生日party的年齡數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
答案:26
程式碼:
#include <iostream> using namespace std; int main() { int ans=0; for(int i=1;i<=99; i++) for(int j=1; j<=50;j++) if( (i+i+j)*(j+1)/2 == 236 ) {ans =i; break;} cout<<ans; return 0; }
3.方格填數
如下的10個格子填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字
答案:1580
程式碼:#include <iostream> #include <cmath> using namespace std; int a[10]={0,1,2,3,4,5,6,7,8,9}; int ans=0; void swap(int a1, int b) { int t = a[a1]; a[a1] = a[b]; a[b] =t ; } void fun (int x) { if(x==10) { if( abs(a[0]-a[1])!=1 && abs(a[0]-a[4])!=1 && abs(a[0]-a[3])!=1 && abs(a[0]-a[5])!=1 && abs(a[1]-a[2])!=1 && abs(a[1]-a[4])!=1 && abs(a[1]-a[5])!=1 && abs(a[1]-a[6])!=1 && abs(a[2]-a[5])!=1 && abs(a[2]-a[6])!=1 && abs(a[3]-a[4])!=1 && abs(a[3]-a[7])!=1 && abs(a[3]-a[8])!=1 && abs(a[4]-a[5])!=1 && abs(a[4]-a[7])!=1 && abs(a[4]-a[8])!=1 && abs(a[4]-a[9])!=1 && abs(a[5]-a[6])!=1 && abs(a[5]-a[8])!=1 && abs(a[5]-a[9])!=1 && abs(a[6]-a[9])!=1 && abs(a[7]-a[8])!=1 && abs(a[8]-a[9])!=1 ) ans++; } for(int i=x; i<10; i++) { swap(x,i); fun(x+1); swap(x,i); } } int main() { fun(0); cout<<ans; return 0; }
4.快速排序
排序在各種場合經常被用到。快速排序是十分常用的高效率的演算法。
其思想是:先選一個“標尺”,
用它把整個佇列過一遍篩子,
以保證:其左邊的元素都不大於它,其右邊的元素都不小於它。
這樣,排序問題就被分割為兩個子區間。
再分別對子區間排序就可以了。
下面的程式碼是一種實現,請分析並填寫劃線部分缺少的程式碼。
#include <stdio.h>
void swap(int a[], int i, int j)
{
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int partition(int a[], int p, int r)
{
int i = p;
int j = r + 1;
int x = a[p];
while(1){
while(i<r && a[++i]<x);
while(a[--j]>x);
if(i>=j) break;
swap(a,i,j);
}
______________________;
return j;
}
void quicksort(int a[], int p, int r)
{
if(p<r){
int q = partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
}
int main()
{
int i;
int a[] = {5,13,6,24,2,8,19,27,6,12,1,17};
int N = 12;
quicksort(a, 0, N-1);
for(i=0; i<N; i++) printf("%d ", a[i]);
printf("\n");
return 0;
}
注意:只填寫缺少的內容,不要書寫任何題面已有程式碼或說明性文字。
答案:swap(a,p,j);
5.消除尾一
下面的程式碼把一個整數的二進位制表示的最右邊的連續的1全部變成0如果最後一位是0,則原數字保持不變。
如果採用程式碼中的測試資料,應該輸出:
00000000000000000000000001100111 00000000000000000000000001100000
00000000000000000000000000001100 00000000000000000000000000001100
請仔細閱讀程式,填寫劃線部分缺少的程式碼。
#include <stdio.h>
void f(int x)
{
int i;
for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
printf(" ");
x = _______________________;
for(i=0; i<32; i++) printf("%d", (x>>(31-i))&1);
printf("\n");
}
int main()
{
f(103);
f(12);
return 0;
}
注意:只填寫缺少的內容,不要書寫任何題面已有程式碼或說明性文字。
答案:x&(x+1)
6.寒假作業
現在小學的數學題目也不是那麼好玩的。看看這個寒假作業:
每個方塊代表1~13中的某一個數字,但不能重複。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算兩種解法。(加法,乘法交換律後算不同的方案)
你一共找到了多少種方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
答案:64
程式碼:
#include<iostream>
#include<algorithm>
using namespace std;
int c=0,a[14],v[14];
void dfs(int s)
{
int i;
if (s>3&&a[1]+a[2]!=a[3])
return ;
if (s>6&&a[4]-a[5]!=a[6])
return ;
if (s>9&&a[7]*a[8]!=a[9])
return ;
if (s>12&&a[12]*a[11]==a[10])
{
c++;
return ;
}
for (i=1;i<=13;i++)
{
if (!v[i])
{
v[i]=1;
a[s]=i;
if (s<13)
dfs(s+1);
v[i]=0;
}
}
}
int main()
{
dfs(1);
cout<<c;
return 0;
}
7.剪郵票
如圖, 有12張連在一起的12生肖的郵票。
(僅僅連線一個角不算相連)
比如圖2,圖3中,粉紅色所示部分就是合格的剪取。
請你計算,一共有多少種不同的剪取方法。
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
程式碼:
#include <iostream>
using namespace std;
int i1, i2, i3, i4, i5;
int visited[13]={1,0,0,1,1,1,1,0,1,1,1,1,1};
bool dfs(int s, int e)
{
if(s==e)
return true;
if(visited[s]!=0)
return false;
visited[s]=1;
if(s-4>=1) if(dfs(s-4,e)) return true;
if(s+4<=12) if(dfs(s+4,e)) return true;
if(s-1>=1&&s-1!=4&&s-1!=8) if(dfs(s-1,e)) return true;
if(s+1<=12&&s+1!=5&&s+1!=9) if(dfs(s+1,e)) return true;
return false;
}
void init()
{
visited[i1]=0;
visited[i2]=0;
visited[i3]=0;
visited[i4]=0;
visited[i5]=0;
}
bool judge()
{
for(int i=0; i<13; i++)
visited[i]=1;
init();
if(!dfs(i1,i2)) return false;
init();
if(!dfs(i1,i3)) return false;
init();
if(!dfs(i1,i4)) return false;
init();
if(!dfs(i1,i5)) return false;
return true;
}
int main(int argc, const char * argv[])
{
int ans=0;
for(i1=1; i1<=8; i1++)
{
for(i2=i1+1; i2<=9; i2++)
{
for(i3=i2+1; i3<=10; i3++)
{
for(i4=i3+1; i4<=11; i4++)
{
for(i5=i4+1; i5<=12; i5++)
{
if(judge()) ans++;
//cout<<i1<<"-"<<i2<<"-"<<i3<<"-"<<i4<<"-"<<i5<<endl;
}
}
}
}
}
cout<<ans;
return 0;
}
8.四平方和
四平方和定理,又稱為拉格朗日定理:每個正整數都可以表示為至多4個正整數的平方和。
如果把0包括進去,就正好可以表示為4個數的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)
對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最後輸出第一個表示法
程式輸入為一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開
例如,輸入:
5
則程式應該輸出:
0 0 1 2
再例如,輸入:
12
則程式應該輸出:
0 2 2 2
再例如,輸入:
773535
則程式應該輸出:
1 1 267 838
資源約定:
峰值記憶體消耗 < 256M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
程式碼:
#include <iostream>
#include <cmath>
using namespace std;
int i1, i2, i3, i4;
int main(int argc, const char * argv[])
{
double n;
cin>>n;
int x1 =(int)sqrt(n/4)+1;
int x2 =(int)sqrt(n/3)+1;
int x3 =(int)sqrt(n/2)+1;
double x4; int x4_;
for(i1=0;i1<=x1;i1++)
{
for(i2=i1;i2<=x2; i2++)
{
for(i3=i2; i3<=x3; i3++)
{
x4=(double)(n-i1*i1-i2*i2-i3*i3);
x4_=(int)sqrt(x4);
if(x4_*x4_ == (int)x4)
{
cout<<i1<<" "<<i2<<" "<<i3<<" "<<x4_<<endl;
return 0;
}
}
}
}
return 0;
}
9.密碼脫落
X星球的考古學家發現了一批古代留下來的密碼。這些密碼是由A、B、C、D 四種植物的種子串成的序列。
仔細分析發現,這些密碼串當初應該是前後對稱的(也就是我們說的映象串)。
由於年代久遠,其中許多種子脫落了,因而可能會失去映象的特徵。
你的任務是:
給定一個現在看到的密碼串,計算一下從當初的狀態,它要至少脫落多少個種子,才可能會變成現在的樣子。
輸入一行,表示現在看到的密碼串(長度不大於1000)
要求輸出一個正整數,表示至少脫落了多少個種子。
例如,輸入:
ABCBA
則程式應該輸出:
0
再例如,輸入:
ABDCDCBABC
則程式應該輸出:
3
資源約定:
峰值記憶體消耗 < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
程式碼:
#include <iostream>
using namespace std;
char s[1002];
int ans=0;
void fun()
{
string x=s;
int en= x.length()-1;
int sa=0;
while(sa<en)
{
if(s[sa]==s[en])
{ sa++; en--;
}
else
{
//左往右移動
int i, j;
for(i=sa+1; i<en; i++)
{
if(s[i]==s[en])
break;
}
for(j=en-1; j>sa; j--)
{ if(s[j]==s[sa])
break;
}
if((i-sa)<(en-j))
{
ans+=i-sa;
sa=i;
}
else
{
ans+=en-j;
en=j;
}
}
}
cout<<ans<<endl;
}
int main(int argc, const char * argv[])
{
cin>>s;
fun();
return 0;
}
10.最大比例
X星球的某個大獎賽設了M級獎勵。每個級別的獎金是一個正整數。並且,相鄰的兩個級別間的比例是個固定值。
也就是說:所有級別的獎金數構成了一個等比數列。比如:
16,24,36,54
其等比值為:3/2
現在,我們隨機調查了一些獲獎者的獎金數。
請你據此推算可能的最大的等比值。
輸入格式:
第一行為數字 N (0<N<100),表示接下的一行包含N個正整數
第二行N個正整數Xi(Xi<1 000 000 000 000),用空格分開。每個整數表示調查到的某人的獎金數額
要求輸出:
一個形如A/B的分數,要求A、B互質。表示可能的最大比例係數
測試資料保證了輸入格式正確,並且最大比例是存在的。
例如,輸入:
3
1250 200 32
程式應該輸出:
25/4
再例如,輸入:
4
3125 32 32 200
程式應該輸出:
5/2
再例如,輸入:
3
549755813888 524288 2
程式應該輸出:
4/1
資源約定:
峰值記憶體消耗 < 256M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
程式碼:
#include <iostream>
#include <algorithm>
using namespace std;
long long num[101];
int son[101];
int mom[101];
int n;
void bubble_sort()
{
int i, now, last=n-1;
while(last>0)
{
for(i=now=0; i<last; i++)
{
if(num[i]>num[i+1])
{
long long t=num[i];
num[i]=num[i+1];
num[i+1]=t;
now =i;
}
}
last=now;
}
}
int fun1(long long x1, long long x2)
{
if(x1%x2 == 0)
return x2;
else
return fun1(x2,x1%x2);
}
int fun2(long long x1, long long x2)
{
if(x2<x1)
{
long long t =x2;
x2=x1;
x1=t;
}
if(x2/x1 == x1)
return x1;
else
return fun2(x2/x1,x1);
}
02
void main_fun()
{
bubble_sort();
int count=0;
for(int i=0; i<n-1; i++)//獲得每一項的倍數
{
if(num[i]!=num[i+1])
{
int t=fun1(num[i+1],num[i]);
son[count]=num[i+1]/t;
mom[count]=num[i]/t;
count++;
}
}
//
for(int i=0; i<count-1; i++)
{
son[i+1]=fun2(son[i],son[i+1]);
mom[i+1]=fun2(mom[i],mom[i+1]);
}
cout<<son[count-1]<<"/"<<mom[count-1];
}
int main(int argc, const char * argv[])
{
cin>>n;
for(int i=0; i<n; i++)
cin>>num[i];
main_fun();
return 0;
}