2016年第七屆藍橋杯試題(C/C++本科B組)
3.湊算式
B DEF
A + --- + ------- = 10
C GHI
(如果顯示有問題,可以參見【圖1.jpg】)
這個算式中A~I代表1~9的數字,不同的字母代表不同的數字。
比如:
6+8/3+952/714 就是一種解法,
5+3/1+972/486 是另一種解法。
這個算式一共有多少種解法?
注意:你提交應該是個整數,不要填寫任何多餘的內容或說明性文字。
思路:不能認為這三個數都是整數,可能3個分數加起來正好組成一個整數,舉個例子啊1/3+2/3=1,前2個數都是分數可結果是整數,用double可能會造成精度問題,所以要最好將式子變一下,ACGHI+BGHI+CDEF=10CGHI
答案:29
5.抽籤
X星球要派出一個5人組成的觀察團前往W星。
其中:
A國最多可以派出4人。
B國最多可以派出2人。
C國最多可以派出2人。
....
那麼最終派往W星的觀察團會有多少種國別的不同組合呢?
下面的程式解決了這個問題。
陣列a[] 中既是每個國家可以派出的最多的名額。
程式執行結果為:
DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,總共101行)
#include <stdio.h>
#define N 6
#define M 5
#define BUF 1024
void f(int a[], int k, int m, char b[])
{
int i,j;
if(k==N){
b[M] = 0;
if(m==0) printf("%s\n",b);
return;
}
for(i=0; i<=a[k]; i++){
for(j=0; j<i; j++) b[M-m+j] = k+'A';
}
}
int main()
{
int a[N] = {4,2,2,1,1,3};
char b[BUF];
f(a,0,M,b);
return 0;
}
仔細閱讀程式碼,填寫劃線部分缺少的內容。
注意:不要填寫任何已有內容或說明性文字。
#include <stdio.h> #define N 6 #define M 5 #define BUF 1024 //a為每個國家可以派出的人數,k為目前正在k國選人,m為剩餘的人數,b為儲存已經選到的人數 void f(int a[], int k, int m, char b[]) { int i,j; //6個國家都選過了 if(k==N){ //相當於b[M] = '\0';加結束符 b[M] = 0; //人都選夠了 if(m==0) printf("%s\n",b); return; } //列舉每個國家選的人數 for(i=0; i<=a[k]; i++){ //選j個k國家的人 for(j=0; j<i; j++) b[M-m+j] = k+'A'; //在剩下的國家中選m-j個人 f(a,k+1,m-j,b); } } int main() { int a[N] = {4,2,2,1,1,3}; char b[BUF]; f(a,0,M,b); return 0; }
7.剪郵票
如【圖1.jpg】, 有12張連在一起的12生肖的郵票。
現在你要從中剪下5張來,要求必須是連著的。
(僅僅連線一個角不算相連)
比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。
請你計算,一共有多少種不同的剪取方法。
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
思路:先列舉每次剪得數字,最後深搜看能否連到一塊
答案:116
public class Main {
static int[][] map = new int[3][4];
static int[] num = new int[5];
//是一個標記每次剪的數的陣列,方便搜尋
static int[][] visit = new int[3][4];
static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}};
//total表示的是滿足條件的總數,can表示的是每次剪時能連到一塊的數量
static int total = 0,can = 0;
public static void main(String[] args) {
int sum = 1;
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
map[i][j] = sum++;
}
}
sum = 1;
for (int i=1; i<=5; i++)
sum *= i;
dfs(0);
//除以5的階乘的原因是12345,12354等5的全排列都能滿足條件,而這是一種剪法
System.out.println(total / sum);
}
private static void dfs(int cur) {
if (cur == 5) {
int x = 0,y = 0;
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
visit[i][j] = 0;
}
}
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
for (int k=0; k<5; k++) {
if (map[i][j] == num[k]) {
visit[i][j] = 1;
x = i;
y = j;
}
}
}
}
can = 0;
judge(x,y);
if (can == 5)
total++;
return;
}
for (int i=1; i<=12; i++) {
int j;
for (j=0; j<cur; j++) {
if (i == num[j])
break;
}
if (j == cur) {
num[cur] = i;
dfs(cur+1);
}
}
}
private static void judge(int x,int y) {
if (visit[x][y] == 0)
return;
can++;
visit[x][y] = 0;
for (int i=0; i<4; i++) {
int newx = x + dir[i][0];
int newy = y + dir[i][1];
if (newx >=0 && newx <=2 && newy >= 0 && newy <= 3)
judge(newx,newy);
}
}
}