本文整理第七屆藍橋杯C組省賽真題(填空與編程題),提供詳細解題思路、優化代碼實現與關鍵陷阱分析,適合競賽備戰與算法訓練參考。
題目:報紙每張紙4頁,撿到一張頁碼為1125,1126,1727,1728,求總頁數。
規律:報紙雙面印刷,單張紙頁碼和為總頁數+1。四頁分兩面:(1125+1126) + (1727+1728) = 2*(總頁數+1)
1125+1126+1727+1728 = 5706
總頁數 = 5706/2 - 1 = 2852
答案:2852
題目:第1層1個,第2層3個,第3層6個,第4層10個……第100層總共多少?
規律:第n層為三角形數T(n) = n(n+1)/2,總和為四面體數Sum = n(n+1)(n+2)/6
// 直接公式法 O(1)
long long n = 100;
long long sum = n * (n+1) * (n+2) / 6; // 171700
// 遞推驗證 O(n)
int getLayer(int n) { // 第n層個數
return n*(n+1)/2;
}
int main() {
long long sum = 0;
for(int i=1; i<=100; i++) sum += getLayer(i);
printf("%lld\n", sum); // 171700
}
答案:171700(注意:原文誤填5050為第100層個數,非總和)
題目:正整數各位平方和迭代,最終收斂到1或進入循環,求循環中最大數。
int next(int n) {
int sum = 0;
while(n) { int d=n%10; sum+=d*d; n/=10; }
return sum;
}
int main() {
int maxv = 0;
for(int start=2; start<1000; start++) { // 足夠大的範圍
int n = start;
for(int i=0; i<100; i++) { // 足夠多迭代
n = next(n);
if(n > maxv) maxv = n;
if(n == 1 || n == 145) break; // 已知循環入口
}
}
printf("%d\n", maxv); // 145
}
循環鏈:145 → 42 → 20 → 4 → 16 → 37 → 58 → 89 → 145,最大值145。
題目:輸出m列n行方格,補全雙層循環。
void f(int m, int n) {
for(int row=0; row
關鍵:外層循環n行,每行打印上邊框+內容,最後補底邊框。
題目:補全partition函數交換基準元素歸位代碼。
int partition(int a[], int p, int r) {
int i = p, j = r + 1, x = a[p];
while(1) {
while(a[++i] < x); // 向右找≥x
while(a[--j] > x); // 向左找≤x
if(i >= j) break;
swap(a, i, j);
}
swap(a, p, j); // ← 填空:基準元素與j位置交換
return j;
}
答案:swap(a, p, j)
題目:A + B/DEF + C/GHI = 10,A-I為1-9不重複,求解數。
關鍵:通分避免浮點誤差,(B*GHI + DEF*C) % (C*GHI) == 0 且商與A和為10。
bool check(int a[]) {
int A=a[0], B=a[1], C=a[2];
int DEF=a[3]*100+a[4]*10+a[5];
int GHI=a[6]*100+a[7]*10+a[8];
int num = B*GHI + DEF*C;
int den = C*GHI;
return (num % den == 0) && (A + num/den == 10);
}
// 全排列DFS,答案:29
題目:1-13填入12個方格,滿足加減乘除四式,交換律算不同解。
bool check(int a[]) {
return (a[0]+a[1]==a[2]) &&
(a[3]-a[4]==a[5]) &&
(a[6]*a[7]==a[8]) &&
(a[9]%a[10]==0 && a[9]/a[10]==a[11]);
}
// 13!全排列DFS,約5分鐘跑完,答案:64
優化方向:預計算乘法對、除法對、加法對,大幅剪枝。
題目:輸入N,求不大於N的所有數經冰雹變換過程中的最大值。
陷阱:原文誤以為只算N自身,實際需遍歷1..N。
int hailstone_max(int n) {
int maxv = n;
while(n != 1) {
n = (n%2==0) ? n/2 : n*3+1;
if(n > maxv) maxv = n;
}
return maxv;
}
int main() {
int N; scanf("%d", &N);
int global_max = N;
for(int i=N; i>=1; i--) // ← 關鍵:從N遞減到1
global_max = max(global_max, hailstone_max(i));
printf("%d\n", global_max);
}
樣例:N=10 → 52;N=100 → 9232
性能優化:備忘錄記錄已計算數的最大高度,避免重複計算。
題目:3×2網格,關羽(A)、張飛(B)、3兵(*)、1空,相鄰移動,求A/B交換最少步數。
解法:狀態壓縮BFS,狀態數6!/(3!) = 120極小,標準BFS即可。
// 狀態編碼:6字符串,空格用'0'
// 目標狀態:A/B位置互換,其他任意
// BFS從初始狀態展開,遇到目標返回步數
提示:使用記憶化搜索/雙向BFS優化。
題目:給定字符串,原為回文,求最少刪除幾字符能變回文(即求最長回文子序列長度,答n - LPS)。
DP定義:dp[i][j]為區間[i,j]最長回文子序列長度。
for(len=1; len<=n; len++)
for(i=0; i+len<=n; i++) {
j = i+len-1;
if(i==j) dp[i][j]=1;
else if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2;
else dp[i][j]=max(dp[i+1][j], dp[i][j-1]);
}
ans = n - dp[0][n-1];
樣例:ABECDCBABC → LPS長度7 → 刪除3個。
祝各位參賽者國賽取得佳績!