13年蓝桥杯 A组 c++真题

真题1:
思路:1.可以用excel 因为出生日期太久远,所以excel对其不能解析 可以将年份加上2000 然后计算
2.模拟翻日历 主要是对以下四点进行判断

  1. 31天的月份 碰到32 要进1 且如果月份为12 时要进1
  2. 30天的月份 碰到31 要进1
  3. 2月份 当是闰年时 碰到30要进1 不是闰年时,碰到29要进1

其中闰年的判断

if((y%4==0&&y%100!=0)||y%400==0)

有个技巧用题目给的数据进行验证

/*
题目标题: 高斯日记

    大数学家高斯有个好习惯:无论如何都要记日记。

    他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210

    后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

    高斯出生于:1777年4月30日。

    在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

    高斯获得博士学位的那天日记上标着:8113

    请你算出高斯获得博士学位的年月日。

提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21

请严格按照格式,通过浏览器提交答案。
注意:只提交这个日期,不要写其它附加内容,比如:说明性的文字。

1799-07-16*/

/* 1 3 5 7 8 10 12*/
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int check(int y){
	if(y%4==0&&y%100!=0) return 1;
	if(y%400==0) return 1;
	return 0;
}
int main(){
	
	int y=1777;
	int m=4;
	int d=30;
	
	for(int i=1;i<8113;i++){
		d++;
		if(d==31&&(m==4||m==6||m==9||m==11)){d=1;m++; continue;}
		if(d==32&&(m==1||m==3||m==5||m==7||m==8||m==10||m==12)){d=1;m++;
		if(m==13) {y++;m=1;} continue;}
		if(d==29&&!check(y)&&m==2){d=1;m++;continue;}
		if(d==30&&check(y)&&m==2){d=1;m++;continue;}
	}
	printf("%d-%d-%d\n",y,m,d);
}

真题2:
题目:
题目标题: 排它平方数

小明正看着 203879 这个数字发呆。

原来,203879 * 203879 = 41566646641

这有什么神奇呢?仔细观察,203879 是个6位数,并且它的每个数位上的数字都是不同的,并且它平方后的所有数位上都不出现组成它自身的数字。

具有这样特点的6位数还有一个,请你找出它!

再归纳一下筛选要求:
1. 6位正整数
2. 每个数位上的数字不同
3. 其平方数的每个数位不含原数字的任何组成数位

答案是一个6位的正整数。

请通过浏览器提交答案。
注意:只提交另一6位数,题中已经给出的这个不要提交。
注意:不要书写其它的内容(比如:说明性的文字)。*/

思路:枚举 首先举出所有各个位数不同的六位数,然后判断其平方是不是包含这里面的数字
key:枚举 !=&&!= 判断包含主要用到取余数

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <set>
using namespace std; 

int main(){
	for(int i=1;i<=9;i++){
		for(int j=0;j<=9;j++)
		if(i!=j){
			for(int k=0;k<=9;k++){
				if(k!=i&&k!=j){
					for(int l=0;l<=9;l++){
						if(l!=k&&l!=i&&l!=j){
							for(int m=0;m<=9;m++){
								if(m!=i&&m!=j&&m!=k&&m!=l){
									for(int n=0;n<=9;n++){
										if(n!=i&&n!=j&&n!=k&&n!=l&&n!=m){
											long long a=i*100000+j*10000+k*1000+l*100+m*10+n;
										   //	cout<<a<<endl;
											long long b=a*a;
											int flag=1;
											while(b){
												int temp=b%10;
												if(temp==i||temp==j||temp==k||temp==l||temp==m||temp==n) {
													flag=0;
											        break;	
										        }
												b/=10;
											}
											if(flag==1)cout<<a<<endl;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

第二种解法里面有一些点需要记住
就是利用 stringstream 在头文件 sstream上 将整数转为字符串 然后用字符串的find函数可以找到是否在里面 ::npos表示末尾

/**
 * 检查xx中是否含有x中的数字
 * @param x
 * @param xx
 * @return
 */
bool check(long long x,long long xx){
	string str_x,str_xx;
	i2s(x,str_x);
	i2s(xx,str_xx);
	
	for(int i=0;i<str_x.length();i++){
		if(str_xx.find(str_x[i])!=string::npos)
		return false;
	}
	return true;
}

void i2s(long long x,string &basic_string ){
	stringstream ss;
	ss<<x;
	ss>>basic_string;
}

真题3:
题目:
标题: 振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案是一个整数,请通过浏览器直接提交该数字。

思路:

  1. 发现并不需要进行判断是否构成语句【因为只要向右和向下走都构成】
  2. 枚举总共条数
  3. 枚举的方法有递归 和 迭代
  4. 递归代码 最重要的是要将问题分解成小问题 在这道题的小问题就是可以向下走和向右走
  5. 递归停止条件就是走到了【边缘】
 #include <iostream>
 #include <algorithm>
 #include <cstdio>
 using namespace std;
 
 int f(int x,int y){
 	if(x==3||y==4) return 1;
 	return f(x+1,y)+f(x,y+1);
 }
 int main(){
 	cout<<f(0,0)<<endl;
 	return 0;
 }

真题4:
题目:
标题: 颠倒的价牌

小李的店里专卖其它店中下架的样品电视机,可称为:样品电视专卖店。

其标价都是4位数字(即千元不等)。

小李为了标价清晰、方便,使用了预制的类似数码管的标价签,只要用颜色笔涂数字就可以了(参见p1.jpg)。

这种价牌有个特点,对一些数字,倒过来看也是合理的数字。如:1 2 5 6 8 9 0 都可以。这样一来,如果牌子挂倒了,有可能完全变成了另一个价格,
比如:1958 倒着挂就是:8561,差了几千元啊!!

当然,多数情况不能倒读,比如,1110 就不能倒过来,因为0不能作为开始数字。

有一天,悲剧终于发生了。某个店员不小心把店里的某两个价格牌给挂倒了。并且这两个价格牌的电视机都卖出去了!

庆幸的是价格出入不大,其中一个价牌赔了2百多,另一个价牌却赚了8百多,综合起来,反而多赚了558元。

请根据这些信息计算:赔钱的那个价牌正确的价格应该是多少?

答案是一个4位的整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。

思路:枚举【好像小题一般都是靠暴力枚举】,然后记得是颠倒 第一次做只有倒 忘记6和9

 #include <iostream>
 #include <algorithm>
 #include <cstdio>
 #include <cstring>
 using namespace std;
 
 int x1[100000];
 int x2[100000];
 int y1[100000];
 int y2[100000];
 
 //1 2 5 6 8 9 0
 int tonum(int x){
 	switch(x){
 		case 1:return 1;
 		case 2:return 2;
 		case 5:return 5;
 		case 6:return 9;
 		case 8:return 8;
 		case 9:return 6;
 		case 0:return 0;
 		default: return 10000;
 	}
 }
 int main(){
 	int lenx=0;
 	int leny=0;
 	for(int i=1000;i<10000;i++){
 		if(i%10==0) continue;
 		int temp=i;
 		int sum=0;
 		while(temp){
 			sum*=10;
 			sum+=tonum(temp%10);
 			temp/=10;
 		}
 		if(i-sum>=200&&i-sum<300){x1[lenx]=i;x2[lenx++]=i-sum;}
 		if(sum-i>=800&&sum-i<900){y1[leny]=i;y2[leny++]=sum-i;}
 	}
 	for(int i=0;i<lenx;i++){
 		for(int j=0;j<leny;j++){
 			if(y2[j]-x2[i]==558){
 				cout<<x1[i]<<endl;
 				return 0;
 			}
 		}
 	}
 	return 0;
 }

真题5:

点赞