藍橋杯 2018 C++ A組 初賽部分題解

題目4
標題:第幾個幸運數
到x星球旅行的遊客都被髮給一個整數,作爲遊客編號。
x星的國王有個怪癖,他只喜歡數字3,5和7。
國王規定,遊客的編號如果只含有因子:3,5,7,就可以獲得一份獎品。
我們來看前10個幸運數字是:3 5 7 9 15 21 25 27 35 45
因而第11個幸運數字是:49
小明領到了一個幸運數字 59084709587505,他去領獎的時候,人家要求他準確地說出這是第幾個幸運數字,否則領不到獎品。
請你幫小明計算一下,59084709587505是第幾個幸運數字。

#include<iostream>
#include<cmath>
using namespace std;

int main(){
	int num_3=0,num_5=0,num_7=0;
	long long int N=59084709587505;
	long long int tmp=N;
	while(tmp!=1){
		if(tmp%3==0){		//分解質因數 只能3、5、7 
			num_3++;
			tmp/=3;
		}
		if(tmp%5==0){
			num_5++;
			tmp/=5;
		}	
		if(tmp%7==0){
			num_7++;
			tmp/=7;
		}
	}
	cout<<N<<"="<<3<<"^"<<num_3<<"*"<<5<<"^"<<num_5<<"*"<<7<<"^"<<num_7<<endl;
	
	int result=0;		//求是第幾個幸運數 
	long long int a=1,b=1,c=1;
   //三層循環暴力求解 
	for(int i=0;i<30;i++){			//3
			if(i==0)		//特殊處理  3的零次冪 
				a=1;
			else
				a*=3;
			if(a>N)			//已經超過值,跳出循環 
				break;
		for(int j=0;j<30;j++){		//5
			if(j==0)
				b=a;
			else
				b*=5;
			if(b>N)
				break;
			for(int k=0;k<30;k++){	//7
				if(k==0)
					c=b;
				else
					c*=7;
				if(c>N)
					break;
					
				result++;
			}
		}	
	}
	cout<<result-1<<endl;			//去掉數字是1的情況	
	return 0;	
}

//別人藉助STL的做法 	可借鑑紫書 醜數  的題解 
#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
const int num[3]={3,5,7};
int main()
{
    priority_queue< ll,vector<ll>,greater<ll> > q;
    set<ll> s;
    s.insert(1);
    q.push(1);
    for(ll i=1;;i++){
        ll x=q.top();
        q.pop();
        if(x==59084709587505){
            cout<<i-1<<endl;
            break;
            }
        for(int j=0;j<3;j++){
            ll x1=x*num[j];
            if(!s.count(x1)){
                s.insert(x1);
                q.push(x1);
            }
        }
    }
    return 0;

題目5
標題:打印圖形

如下的程序會在控制檯繪製分形圖(就是整體與局部自相似的圖形)。

當n=1,2,3的時候,輸出如下:
n=1時:
在這裏插入圖片描述
n=2時:
在這裏插入圖片描述
n=3時:
在這裏插入圖片描述

//很有意思的一題  利用遞歸畫圖 填空很簡單 
#include <stdio.h>
#include <stdlib.h>

void show(char* buf, int w){
	int i,j;
	for(i=0; i<w; i++){
		for(j=0; j<w; j++){
			printf("%c", buf[i*w+j]==0? ' ' : 'o');
		}
	printf("\n");	
	}	
}

void draw(char* buf, int w, int x, int y, int size){
	if(size==1){
		buf[y*w+x] = 1;		//類似哈希函數 
	return;
	}
	
	int n = size/3;			//blank filling
	draw(buf, w, x, y, n);		//遞歸 
	draw(buf, w, x-n, y ,n);
	draw(buf, w, x+n, y ,n);
	draw(buf, w, x, y-n ,n);
	draw(buf, w, x, y+n ,n);
}

int main()
{
	int N = 3;
	int t = 1;
	int i;
	for(i=0; i<N; i++) 
		t *= 3;
	
	char* buf = (char*)malloc(t*t);
	
	for(i=0; i<t*t; i++)
		buf[i] = 0;
	
	draw(buf, t, t/2, t/2, t);
	show(buf, t);
	free(buf);

	return 0;
}

 //藍橋杯第六題		航班時間
#include <stdio.h>
//格式化輸出
void printFormat( int t, char c) {
	if( t<10) printf( "0%d%c", t, c);
	else printf(  "%d%c", t, c);
}
 
int main()
{
	int n; char c; //輸入數據組數
	scanf( "%d", &n);
	int flyTime[n]; //flytime 單位:秒
	
	int i = 2*n;
	while( i--) {
		if( i%2) flyTime[i/2] = 0; //初始化
		
		int h1, m1, s1, h2, m2, s2;
		scanf( "%d:%d:%d %d:%d:%d", &h1, &m1, &s1, &h2, &m2, &s2);
		flyTime[i/2] += 60*60*(h2-h1)+60*(m2-m1)+(s2-s1);		//都轉換爲秒 
		
		//處理次日、第三天到達情況
		while( (c=getchar())!='\n') {
			if( c=='+') flyTime[i/2] += 24*60*60*(getchar()-'0');
		}
	}
	
	for( i=n-1; i>=0; i--) {
		flyTime[i] /= 2;
		printFormat( flyTime[i]/3600, ':');        //hour
		printFormat( flyTime[i]/60%60, ':');       //minute
		printFormat( flyTime[i]%60, '\n');         //second
	}
	
	return 0;
}

第八題 標題:全球變暖

【題目描述】
你有一張某海域NxN像素的照片,".“表示海洋、”#"表示陸地,如下所示:
在這裏插入圖片描述
其中"上下左右"四個方向上連在一起的一片陸地組成一座島嶼。例如上圖就有2座島嶼。
由於全球變暖導致了海面上升,科學家預測未來幾十年,島嶼邊緣一個像素的範圍會被海水淹沒。具體來說如果一塊陸地像素與海洋相鄰(上下左右四個相鄰像素中有海洋),它就會被淹沒。
例如上圖中的海域未來會變成如下樣子:
在這裏插入圖片描述
請你計算:依照科學家的預測,照片中有多少島嶼會被完全淹沒。

【輸入格式】
第一行包含一個整數N。 (1 <= N <= 1000)
以下N行N列代表一張海域照片。
照片保證第1行、第1列、第N行、第N列的像素都是海洋。

【輸出格式】
一個整數表示答案。

【樣例輸入】
7

.##…
.##…
…##.
…####.
…###.

【樣例輸出】
1

//有更加簡單的方法 以下代碼純粹想提高編程能力 
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

typedef pair<int,int> Pair;		//將行\列存爲一對,避免維度增多 
const int next_r[4]={0,0,-1,1};		//移動的四個方向 
const int next_c[4]={1,-1,0,0};
const int maxn=1000+1;
int N;
bool vis[maxn][maxn];			//節點是否被訪問過 
char graph[maxn][maxn];			//節點信息 
vector<Pair> island[maxn];		//島嶼的結點信息 
vector<Pair>::iterator IT;
bool ischange[maxn][maxn];		//該陸地是否會淹沒 

bool check(int r,int c){			//判斷新的訪問結點是否合法 
	if(r>=0&&r<N&&c>=0&&c<N && graph[r][c]=='#')	//沒有超出圖的邊界而且是陸地 
		if(!vis[r][c])			//還要沒有被訪問過 
			return true;
	return false;
}

void find_island(int r,int c,int num){		//num是屬於的島嶼編號 
	int newr,newc;
	vis[r][c]=1;		//更新vis 
	island[num].push_back(Pair(r,c));		//行\列信息存到island中 
	for(int q=0;q<4;q++){
		newr=r+next_r[q];		//尋找下一塊連通的陸地 
		newc=c+next_c[q];		
		if(check(newr,newc)){		//檢驗可行性 
			find_island(newr,newc,num);
		}
	}
}
  
void change(){
	int newr,newc;
	for(int i=1;i<N-1;i++)				//邊界已經保證爲海洋 
		for(int j=1;j<N-1;j++)
			if(graph[i][j]=='#')
				for(int k=0;k<4;k++){
					newr=i+next_r[k];
					newc=j+next_c[k];
					if(graph[newr][newc]=='.'){		//只要有一片大海 
						ischange[i][j]=1;			//不能立馬更新,因爲會影響到周邊陸地 
						break; 
					} 
				}

	for(int i=1;i<N-1;i++)			//更新結點信息	 
		for(int j=1;j<N-1;j++)	
			if(ischange[i][j]==1)
				graph[i][j]='.';
	
}
  
int refind_island(int num){
	int ans=0;
	for(int i=0;i<num;i++){
		int code=1;
		for(IT=island[i].begin();IT!=island[i].end();IT++){
			if(graph[(*IT).first][(*IT).second]=='#'){		//島嶼有一塊陸地就還存在 
				code=0;
				break;			//跳出循環,遍歷下一個島嶼 
			}
		}
		if(code)
			ans++;			//淹沒的島嶼 +1 
	}
	return ans;
}
  
int main(){
	memset(ischange,0,sizeof(ischange));
	memset(vis,0,sizeof(vis));
	cin>>N;
	for(int i=0;i<N;i++)		//輸入二維數組 
		for(int j=0;j<N;j++){
			cin>>graph[i][j];
			
		}
		
	int v=0;  	//島嶼編號 
	for(int i=1;i<N-1;i++)
		for(int j=1;j<N-1;j++){
			if(!vis[i][j]&&graph[i][j]=='#'){		//找出滿足條件的一塊島嶼開始的陸地 
				find_island(i,j,v);		//利用dfs求屬於一個島嶼的陸地(並查集貌似也行) 
				v++;
			}
		}
	change();		//大海淹沒 
	
	cout<<refind_island(v)<<endl;		//消失的島嶼 
	
	return 0;	
}

[上面借鑑的代碼及題目來自 https://blog.csdn.net/zhanw15/article/details/79845250
以及這裏 https://blog.csdn.net/linruier2017/article/details/79782950

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