第九屆藍橋杯省賽A組

第一題
標題:分數
1/1 + 1/2 + 1/4 + 1/8 + 1/16 + …
每項是前一項的一半,如果一共有20項,
求這個和是多少,結果用分數表示出來。
類似:3/2
當然,這只是加了前2項而已。分子分母要求互質。
注意:
需要提交的是已經約分過的分數,中間任何位置不能含有空格。請不要填寫任何多餘的文字或符號。
解析:等比數列求和公式,手算。
s=a1(1-q^n)/1-q;
第2題
標題:星期一
整個20世紀(1901年1月1日至2000年12月31日之間),一共有多少個星期一?
(不要告訴我你不知道今天是星期幾)
注意:需要提交的只是一個整數,不要填寫任何多餘的內容或說明文字。
解析:計算總共多少天。對7求商取餘數。再根據最後一天是周幾往前走餘數天看能夠走到題目要求的週一,如果能則結果爲爲商加一,不能結果爲商。

#include"stdio.h"
int month[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int is_runian(int year)
{
	if((year%4==0&&year% 100!=0)||year%400==0)//400的倍數,4的倍數但不是100的倍數。
	{
	return 1; 
	} 
	else
	return 0;
}
int main()
{
    int day=0;
    int i;
    for (i=1901;i<=2000;i++)
    {
    	if (is_runian(i))
		{
			day=day+366;
		 } 
		 else
		 {
		 	day=day+365;
		 }
	} 
	int yushu=0;
	yushu=day%7;
	day=day/7;
	printf("%d %d",day,yushu);
	return 0;
 } 
 //輸出5127 6  餘數6   2000年12月31日是星期天。週日往前數6個,不是週一,所以不加一。答案5127 

第3題
標題:乘積尾零
如下的10行數據,每行有10個整數,請你求出它們的乘積的末尾有多少個零?
5650 4542 3554 473 946 4114 3871 9073 90 4329
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899
1486 5722 3135 1170 4014 5510 5120 729 2880 9019
2049 698 4582 4346 4427 646 9742 7340 1230 7683
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649
6701 6645 1671 5978 2704 9926 295 3125 3878 6785
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074
689 5510 8243 6114 337 4096 8199 7313 3685 211
解析:
直接計算會爆掉。末尾有多少零,因爲只有2和5相乘,纔會出現0。所以只要統計數中2和5最小的那個總數。

#include"stdio.h"

int  result_2=0;//記錄因子2的個數 
int  result_5=0;//記錄因子5的個數 
/*
將value分解看有多少個2多少個5 
*/
void fenjie(int value)
{  
    result_2=0;
    result_5=0;
	     while(value % 2==0) //統計因子2的個數 
		 {
		 	result_2++;	
			value=value/2;//統計i因子後除去i因子 	
		 }
		 while(value % 5==0)//統計因子5的個數  
		 {
		 	result_5++;	
			value=value/5;//統計i因子後除去i因子 	
			 }
}
int main()
{
int a[]={5650 ,4542 ,3554 ,473, 946, 4114 ,3871, 9073, 90, 4329,
2758 ,7949, 6113, 5659, 5245, 7432, 3051, 4434, 6704, 3594,
9937 ,1173, 6866, 3397, 4759, 7557, 3070, 2287, 1453, 9899,
1486 ,5722, 3135, 1170, 4014, 5510, 5120, 729, 2880, 9019,
2049, 698, 4582, 4346, 4427, 646, 9742, 7340 ,1230 ,7683,
5693 ,7015, 6887, 7381, 4172, 4341 ,2909, 2027 ,7355, 5649,
6701 ,6645 ,1671 ,5978 ,2704 ,9926, 295 ,3125 ,3878 ,6785,
2066 ,4247, 4800 ,1578, 6652, 4616 ,1113, 6205, 3264, 2915,
3966, 5291 ,2904 ,1285, 2193 ,1428 ,2265, 8730 ,9436 ,7074,
689 ,5510, 8243, 6114 ,337, 4096, 8199, 7313, 3685, 211
};
int len;
len = sizeof(a)/sizeof(int);//數組長度 
int total_result2=0,total_result5=0; //儲存2和5的個數 
int result=0;//保存結果 
for (int i=0;i<len;i++)
{
	fenjie(a[i]);
	total_result2=total_result2+result_2;
	total_result5=total_result5+result_5;
}
if(total_result2>total_result5)
{
	result=total_result5;
}
else
{
	result=total_result2; 
	}
printf("%d",result);
return 0;
}

在這裏插入圖片描述
第4題
標題:第幾個幸運數
到x星球旅行的遊客都被髮給一個整數,作爲遊客編號。x星的國王有個怪癖,他只喜歡數字3,5和7。
國王規定,遊客的編號如果只含有因子:3,5,7,就可以獲得一份獎品。我們來看前10個幸運數字是:3 5 7 9 15 21 25 27 35 45 因而第11個幸運數字是:49 小明領到了一個幸運數字 59084709587505,他去領獎的時候,人家要求他準確地說出這是第幾個幸運數字,否則領不到獎品。請你幫小明計算一下,59084709587505是第幾個幸運數字。需要提交的是一個整數,請不要填寫任何多餘內容。
解:分析國王喜歡的數 =3^a
*5^b
*7^c(a,b,c不可同時爲0);
利用廣度優先搜索做,用一個隊列裝幸運數,從3,5,7出發,依次將隊首乘3,5,7的結果加入隊尾(注意判重),直到出現目標59084709587505.注意找到目標後,目標位置之前還有符合題意的,還需要一次廣度優先搜索。
在這裏插入圖片描述

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
long long q[10000];
int mul[3]={3,5,7};
int main()
{
memset(q,sizeof(q),0);//清零隊列q 
q[0]=3;
q[1]=5;
q[2]=7;
int front=0;//頭指針  
int rear=3;//尾指針位置爲最後一個元素位置加1 
while(front<rear) //隊列不空  
{
	for(int i=0;i<3;i++)
	{
		if(q[front]*mul[i]>59084709587505)//大於59084709587505的排在後面的不加入隊列。 
			continue; 
		long long t=q[front]*mul[i];//產生一個新的數 
		bool exist=0;//去重標誌,等於0,數沒在隊列中,可以將新數加入隊列。等於1,數已經在隊列中,不可再加入隊列。 
		for(int j=rear-1;j>=0;j--)
		{  if(q[j]==t)
			{
				exist=1;//t在隊列中 
				break;
			}
		} 
		if(!exist) // 
		{
			q[rear]=t;
			rear++;//將t入隊 
			if(t==59084709587505)//此時隊尾元素已經是59084709587505,但還存在front到rear之間的元素和3,5,7相乘的結果小於59084709587505的可能 
			{
				for(int k=front;k<rear-1;)//以上<59084709587505的可能情況,都應加入隊列中 
				{
					for(int i=0;i<3;i++)
					{
						long long t=q[k]*mul[i];
						if(t<59084709587505)
						{
							bool exist=0;//去重標誌,等於0,數沒在隊列中,可以將新數加入隊列。等於1,數已經在隊列中,不可再加入隊列。 
							for(int j=rear-1;j>=0;j--)
								{  if(q[j]==t)
									{
										exist=1;//t在隊列中  
										break;
									}
								}	
							if(!exist) //不在隊列中入隊 
								{
									q[rear]=t;
									rear++;
								}
						}
					}
					k++; 
				}
				sort(q,q+rear);//對3到59084709587505的幸運數進行排序 
				int pos=rear-1;
				while(q[pos]!=59084709587505)
				{	pos--;//查找排序後的59084709587505所在的下標序號 
				} 
				cout<<pos+1<<endl;//因爲是從隊列位置從0開始的所以要加一 
				return 0;
			}
		}
	}
   front++; //頭指針下移一個位置 
}
return 0;	
} 

在運行結果1905這裏插入圖片描述

第6題
標題:航班時間
【問題背景】
小h前往美國參加了藍橋杯國際賽。小h的女朋友發現小h上午十點出發,上午十二點到達美國,於是感嘆到“現在飛機飛得真快,兩小時就能到美國了”。
小h對超音速飛行感到十分恐懼。仔細觀察後發現飛機的起降時間都是當地時間。由於北京和美國東部有12小時時差,故飛機總共需要14小時的飛行時間。
不久後小h的女朋友去中東交換。小h並不知道中東與北京的時差。但是小h得到了女朋友來回航班的起降時間。小h想知道女朋友的航班飛行時間是多少。
【問題描述】
對於一個可能跨時區的航班,給定來回程的起降時間。假設飛機來回飛行時間相同,求飛機的飛行時間。
【輸入格式】
從標準輸入讀入數據。
一個輸入包含多組數據。
輸入第一行爲一個正整數T,表示輸入數據組數。
每組數據包含兩行,第一行爲去程的 起降 時間,第二行爲回程的 起降 時間。
起降時間的格式如下
h1:m1:s1 h2:m2:s2

h1:m1:s1 h3:m3:s3 (+1)

h1:m1:s1 h4:m4:s4 (+2)
表示該航班在當地時間h1時m1分s1秒起飛,
第一種格式表示在當地時間 當日 h2時m2分s2秒降落
第二種格式表示在當地時間 次日 h3時m3分s3秒降落。
第三種格式表示在當地時間 第三天 h4時m4分s4秒降落。
對於此題目中的所有以 hⓂ️s 形式給出的時間, 保證 ( 0<=h<=23, 0<=m,s<=59 ).
【輸出格式】
輸出到標準輸出。
對於每一組數據輸出一行一個時間hh:mm:ss,表示飛行時間爲hh小時mm分ss秒。
注意,當時間爲一位數時,要補齊前導零。如三小時四分五秒應寫爲03:04:05。
【樣例輸入】
3
17:48:19 21:57:24
11:05:18 15:14:23
17:21:07 00:31:46 (+1)
23:02:41 16:13:20 (+1)
10:19:19 20:41:24
22:19:04 16:41:09 (+1)
【樣例輸出】
04:09:05
12:10:39
14:22:05
【限制與約定】
保證輸入時間合法,飛行時間不超過24小時。
資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗 < 1000ms
請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入…” 的多餘內容。
注意:
main函數需要返回0;
只使用ANSI C/ANSI C++ 標準;
不要調用依賴於編譯環境或操作系統的特殊函數。
所有依賴的函數必須明確地在源文件中 #include
不能通過工程設置而省略常用頭文件。
提交程序時,注意選擇所期望的語言類型和編譯器類型。
解析;去程:起飛時間1+時差+飛行時間=到達目的地時間1
歸程:起飛時間2-時差+飛行時間=到達目的地時間2。
所以 起飛時間1+起飛時間2+2*飛行時間=到達目的地時間1+到達目的地時間2
即:飛行時間=(到達目的地時間1+到達目的地時間2-起飛時間1-起飛時間2)/2;


//#include"stdio.h"
#include"cstdio"
#include"iostream"
#include"string"
using namespace std; 
int input1()
{
	int hour,min,sec,time; 
	scanf("%d:%d:%d",&hour,&min,&sec);//輸入的時候用英文的: 
	//printf("%d:%d:%d\n",hour,min,sec);
	time=hour*3600+min*60+sec;
	return time;
 } 
int input2()
{
	int hour,min,sec,time,day=0;
	char ch;
	scanf("%d:%d:%d",&hour,&min,&sec); 
	ch=getchar();
	while(ch!='\n')
	{
		if(isdigit(ch))//ch='0'-'9'返回1,否則返回0 
        {
          day=ch-'0';  	
		  }
		ch=getchar();
	}
	time=day*24*60*60+hour*60*60+min*60+sec;//化成秒 
	return time;
}
void output(int flytime) //秒轉化爲小時,分鐘,秒輸出 
{    
    int hour,min,sec;
	hour=flytime/3600;
	min=(flytime-hour*3600)/60;
	sec=flytime-hour*3600-min*60;
	printf("%02d:%02d:%02d\n",hour,min,sec);//區域寬度爲2,不足爲0. 大於兩位則原樣輸出
}
int main()
{
	int N;
	int flyTime=0;
	int startFly1,startFly2,arriveFly1,arriveFly2;\
	scanf("%d",&N);
	while(N--)
	{
	 startFly1=input1();//起飛時間1 
	 arriveFly1=input2();
	 startFly2=input1();//起飛時間1 
	 arriveFly2=input2(); 
	 flyTime=(arriveFly1+arriveFly2-startFly1-startFly2)/2;
	 output(flyTime);
	} 
	return 0; 

在這裏插入圖片描述第9題
標題:倍數問題
【題目描述】
衆所周知,小蔥同學擅長計算,尤其擅長計算一個數是否是另外一個數的倍數。
但小蔥只擅長兩個數的情況,當有很多個數之後就會比較苦惱。
現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數,使得這三個數的和是 K 的倍數,且這個和最大。
數據保證一定有解。
【輸入格式】
從標準輸入讀入數據。
第一行包括 2 個正整數 n, K。
第二行 n 個正整數,代表給定的 n 個數。
【輸出格式】
輸出到標準輸出。
輸出一行一個整數代表所求的和。
【樣例入】
4 3
1 2 3 4
【樣例輸出】
9

【樣例解釋】
選擇2、3、4。

/*用數組num[n]儲存n個數,第一個數有num[0]到num[n-1]種可能,第二個數有除去第一個數的n-1種可能,
第三個數有出去第二個數的n-2種可能/*
第一個數對 num[0]到num[n-1]種可能嘗試,for循環 
第二個數   num[0]到num[n-1]-1種可能嘗試,for循環 
第三個數   num[0]到num[n-1]-2種可能嘗試,for循環 
求三個數的方法相同,遞歸。深度優先搜索用遞歸實現,分而治之的思想。 */

#include"stdio.h"
int a[1000]={0};
int result[3];
int flag[1000]={0};//flag[i],用來標記num[i]是否已被使用,=1被使用,=0沒有被使用 
int sum;
int n,k; 
int ans; 
int i;
void dfs(int s) //深度優先搜索 
{
	if(s==3)
	{
		sum=result[0]+result[1]+result[2];
		if((sum%k==0)&&sum>ans)
	     {
	     	ans=sum;//更新結果  
		 }
		 return;//返回結果  
	} 
	int i;
	for(i=0;i<n;i++) //每一個數都有num[0]到num[n]種可能 
	{
		if(!flag[i])   //判斷a[i]是否被使用  
		{
			result[s]=a[i];//將數據a[i]納入結果  
			flag[i]=1;//標記a[i]被使用  
			dfs(s+1);//查找下一個數 
			flag[i]=0;//取消標記a[i]被使用  
		}
	 } 
}
int main()
{
	scanf("%d %d",&n,&k);//
	for(i=0;i<n;i++) 
	{
	 scanf("%d",&a[i]);
	}
	dfs(0);//深度優先搜索  
   printf("%d",ans); 
}

在這裏插入圖片描述

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