蓝桥杯 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

发布了17 篇原创文章 · 获赞 2 · 访问量 440

猜你喜欢

转载自blog.csdn.net/Raymond_YP/article/details/104241622