第七屆藍橋杯大賽個人賽省賽C++ A組 題解+原題 (填空題)

1.網友年齡

某君新認識一網友。

當問及年齡時,他的網友說:

“我的年齡是個2位數,我比兒子大27歲,

如果把我的年齡的兩位數字交換位置,剛好就是我兒子的年齡”

請你計算:網友的年齡一共有多少種可能情況?

提示:30歲就是其中一種可能哦.

請填寫表示可能情況的種數。

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

i*10+j-j*10-i =27
9*i-9*j = 27
i-j = 3


答案:7    (30 41 52 63 74 85 96)

2.生日蠟燭

某君從某年開始每年都舉辦一次生日party,並且每次都要吹熄與年齡相同根數的蠟燭。

現在算起來,他一共吹熄了236根蠟燭。

請問,他從多少歲開始過生日party的?

請填寫他開始過生日party的年齡數。

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

解題思路:直接逐一枚舉就可以求出來

答案:26

代碼如下:
#include <stdio.h>
#include <math.h>
int main()
{
	int a[101];
	a[0]=0;
	for(int i=1;i<=100;i++)
		a[i]=a[i-1]+i;
	for (int i = 1; i < 100; ++i)
		for (int j = 2; j <= 100; ++j)
			if(a[j]-a[i] == 236) {printf("%d %d\n",j,i);}
	return 0;
}

3. 方格填數


如下的10個格子
   +--+--+--+
   |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+


(如果顯示有問題,也可以參看【圖1.jpg】)


填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)


一共有多少種可能的填數方案?


請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。

解題思路:如果說不怎麼會搜索,那麼就只能用死辦法,暴力枚舉出來了,如果會搜索的,那麼就直接dfs就出來了。。。

答案:1580



代碼一:暴力暴力(代碼看起來有點嚇人)-----for
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;

int main()
{
	int s[15]={0},ans=0;
	for (int a = 1; a < 11; ++a)
	{
		if(s[a]) continue;
		s[a]=1;
		for (int b = 1; b < 11; ++b)
		{
			if(s[b] || abs(b-a)==1) continue;
			s[b]=1;
			for (int c = 1; c < 11; ++c)
			{
				if(s[c] || abs(c-b)==1) continue;
				s[c]=1;
				for (int d = 1; d < 11; ++d)
				{
					if(s[d] || abs(d-a)==1) continue;
					s[d]=1;
					for (int e = 1; e < 11; ++e)
					{
						if(s[e] || abs(e-a)==1 || abs(e-d)==1 || abs(e-b)==1) continue;
						s[e]=1;
						for (int f = 1; f < 11; ++f)
						{
							if(s[f] || abs(f-a)==1 || abs(f-b)==1 || abs(f-c)==1 || abs(f-e)==1) continue;
							s[f]=1;
							for (int g = 1; g < 11; ++g)
							{
								if(s[g]  || abs(g-b)==1 || abs(g-c)==1 || abs(g-f)==1) continue;
								s[g]=1;
								for (int h = 1; h < 11; ++h)
								{
									if(s[h] || abs(h-d)==1 || abs(h-e)==1) continue;
									s[h]=1;
									for (int i = 1; i < 11; ++i)
									{
										if(s[i]  || abs(i-d)==1 || abs(i-e)==1 || abs(i-h)==1 || abs(i-f)==1) continue;
										s[i]=1;
										for(int j=1;j<11;j++)
										{
											if(s[j]  || abs(j-e)==1 || abs(j-f)==1 || abs(j-i)==1 || abs(j-g)==1) continue;
											ans++;
										}
										s[i]=0;
									}
									s[h]=0;
								}
								s[g]=0;
							}
							s[f]=0;
						}
						s[e]=0;
					}
					s[d]=0;
				}
				s[c]=0;
			}
			s[b]=0;
		}
		s[a]=0;
	}
	printf("%d\n",ans);
	return 0;
}

代碼二:搜索-----dfs
#include <stdio.h>
#define LL long long
#define INF 0x3f3f3f3f
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[4][5],vis[11],ans=0;
int f[4][2]={-1,-1, 0,-1, -1,1, -1,0};
int fun(int s,int x,int y)
{
	for (int i = 0; i < 4; ++i)
	{
		int fx = x+f[i][0];
		int fy = y+f[i][1];
		if(fx<1 || fx>3 || fy<1 || fy>4) continue;
		if(abs(s-a[fx][fy])==1) return 0;
	}
	return 1;
}
void dfs(int x,int y)
{
	if(x==3 && y==4)
		{ans++; return;}
	for(int i=0;i<10;i++)
	{
		if(vis[i] || !fun(i,x,y)) continue;
		vis[i]=1;
		a[x][y]=i;
		if(y==4) dfs(x+1,1);
		else dfs(x,y+1);
		vis[i]=0;
		a[x][y]=-INF;
	}
}
int main()
{	
	for(int i=1;i<4;i++)
		for(int j=1;j<5;j++)
			a[i][j]=-INF;
	dfs(1,2);
	printf("%d\n",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,i,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.jpg】)

  

每個方塊代表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


解題思路:這題和第三題一樣的,可以暴力也可以dfs,只要控制好判斷條件就可以了。。。

代碼一:暴力暴力----for
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;

int main()
{
	int s[15]={0},ans=0;
	for (int a = 1; a < 14; ++a)
	{
		if(s[a]) continue;
		s[a]=1;
		for (int b = 1; b < 14; ++b)
		{
			if(s[b]) continue;
			s[b]=1;
			for (int c = 1; c < 14; ++c)
			{
				if(s[c] || a+b!=c) continue;
				s[c]=1;
				for (int d = 1; d < 14; ++d)
				{
					if(s[d]) continue;
					s[d]=1;
					for (int e = 1; e < 14; ++e)
					{
						if(s[e]) continue;
						s[e]=1;
						for (int f = 1; f < 14; ++f)
						{
							if(s[f] || d-e!=f) continue;
							s[f]=1;
							for (int g = 1; g < 14; ++g)
							{
								if(s[g]) continue;
								s[g]=1;
								for (int h = 1; h < 14; ++h)
								{
									if(s[h]) continue;
									s[h]=1;
									for (int i = 1; i < 14; ++i)
									{
										if(s[i] || g*h!=i) continue;
										s[i]=1;
										for (int j = 1; j < 14; ++j)
										{
											if(s[j]) continue;
											s[j]=1;
											for (int k = 1; k < 14; ++k)
											{
												if(s[k]) continue;
												s[k]=1;
												for (int l = 1; l < 14; ++l)
												{
													if(s[l]) continue;
													if(k*l == j) {
														printf("%d %d %d %d %d %d %d %d %d %d %d %d ",a,b,c,d,e,f,g,h,i,j,k,l); ans++;
													}
												}
												s[k]=0;
											}
											s[j]=0;
										}
										s[i]=0;
									}
									s[h]=0;
								}
								s[g]=0;
							}
							s[f]=0;
						}
						s[e]=0;
					}
					s[d]=0;
				}
				s[c]=0;
			}
			s[b]=0;
		}
		s[a]=0;
	}
	printf("%d\n",ans);
	return 0;
}

代碼二:搜索----dfs
#include <stdio.h>
#define LL long long
#define INF 0x3f3f3f3f
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
int ans=0;
int vis[14],a[13];
void dfs(int x)
{
	if( (x==4&& a[1]+a[2]!=a[3]) || (x==7&& a[4]-a[5]!=a[6]) || (x==10&& a[7]*a[8]!=a[9]) || (x==13&& a[11]*a[12]!=a[10])) return;
	if(x ==13) {ans++; return;}
	for(int i=1;i<=13;i++)
	{
		if(vis[i]) continue;
		vis[i]=1;
		a[x]=i;
		dfs(x+1);
		a[x]=-1;
		vis[i]=0;
	}
}
int main()
{	
	dfs(1);
	printf("%d\n",ans);
	return 0;
}
所有的符合條件:
1 8 9 13 6 7 2 5 10 12 3 4     1 8 9 13 6 7 2 5 10 12 4 3     1 8 9 13 6 7 3 4 12 10 2 5
1 8 9 13 6 7 3 4 12 10 5 2     1 8 9 13 6 7 4 3 12 10 2 5     1 8 9 13 6 7 4 3 12 10 5 2
1 8 9 13 6 7 5 2 10 12 3 4     1 8 9 13 6 7 5 2 10 12 4 3     1 8 9 13 7 6 2 5 10 12 3 4
1 8 9 13 7 6 2 5 10 12 4 3     1 8 9 13 7 6 3 4 12 10 2 5     1 8 9 13 7 6 3 4 12 10 5 2
1 8 9 13 7 6 4 3 12 10 2 5     1 8 9 13 7 6 4 3 12 10 5 2     1 8 9 13 7 6 5 2 10 12 3 4
1 8 9 13 7 6 5 2 10 12 4 3     6 7 13 9 1 8 2 5 10 12 3 4     6 7 13 9 1 8 2 5 10 12 4 3
6 7 13 9 1 8 3 4 12 10 2 5     6 7 13 9 1 8 3 4 12 10 5 2     6 7 13 9 1 8 4 3 12 10 2 5
6 7 13 9 1 8 4 3 12 10 5 2     6 7 13 9 1 8 5 2 10 12 3 4     6 7 13 9 1 8 5 2 10 12 4 3
6 7 13 9 8 1 2 5 10 12 3 4     6 7 13 9 8 1 2 5 10 12 4 3     6 7 13 9 8 1 3 4 12 10 2 5
6 7 13 9 8 1 3 4 12 10 5 2     6 7 13 9 8 1 4 3 12 10 2 5     6 7 13 9 8 1 4 3 12 10 5 2
6 7 13 9 8 1 5 2 10 12 3 4     6 7 13 9 8 1 5 2 10 12 4 3     7 6 13 9 1 8 2 5 10 12 3 4
7 6 13 9 1 8 2 5 10 12 4 3     7 6 13 9 1 8 3 4 12 10 2 5     7 6 13 9 1 8 3 4 12 10 5 2
7 6 13 9 1 8 4 3 12 10 2 5     7 6 13 9 1 8 4 3 12 10 5 2     7 6 13 9 1 8 5 2 10 12 3 4
7 6 13 9 1 8 5 2 10 12 4 3     7 6 13 9 8 1 2 5 10 12 3 4     7 6 13 9 8 1 2 5 10 12 4 3
7 6 13 9 8 1 3 4 12 10 2 5     7 6 13 9 8 1 3 4 12 10 5 2     7 6 13 9 8 1 4 3 12 10 2 5
7 6 13 9 8 1 4 3 12 10 5 2     7 6 13 9 8 1 5 2 10 12 3 4     7 6 13 9 8 1 5 2 10 12 4 3
8 1 9 13 6 7 2 5 10 12 3 4     8 1 9 13 6 7 2 5 10 12 4 3     8 1 9 13 6 7 3 4 12 10 2 5
8 1 9 13 6 7 3 4 12 10 5 2     8 1 9 13 6 7 4 3 12 10 2 5     8 1 9 13 6 7 4 3 12 10 5 2
8 1 9 13 6 7 5 2 10 12 3 4     8 1 9 13 6 7 5 2 10 12 4 3     8 1 9 13 7 6 2 5 10 12 3 4
8 1 9 13 7 6 2 5 10 12 4 3     8 1 9 13 7 6 3 4 12 10 2 5     8 1 9 13 7 6 3 4 12 10 5 2
8 1 9 13 7 6 4 3 12 10 2 5     8 1 9 13 7 6 4 3 12 10 5 2     8 1 9 13 7 6 5 2 10 12 3 4
8 1 9 13 7 6 5 2 10 12 4 3     

7. 剪郵票

如【圖1.jpg】, 有12張連在一起的12生肖的郵票。

現在你要從中剪下5張來,要求必須是連着的。

(僅僅連接一個角不算相連)

比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。

 

請你計算,一共有多少種不同的剪取方法。

 

請填寫表示方案數目的整數。

注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。


答案:116



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章