2016年蓝桥杯C语言混搭 C/C++题解

摘录《读者》片段以表达今日份感慨:

今天的小鱼吃饱喝足后依旧元气满满呢!(就是——开学该减肥啦……)


1.报纸页数

X星球日报和我们地球的城市早报是一样的,
都是一些单独的纸张叠在一起而已。每张纸印有4版。

比如,某张报纸包含的4页是:5,6,11,12,
可以确定它应该是最上边的第2张报纸。

我们在太空中捡到了一张X星球的报纸,4个页码分别是:
1125,1126,1727,1728

请你计算这份报纸一共多少页(也就是最大页码,并不是用了几张纸哦)?

请填写表示总页数的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
 

#include<iostream>
using namespace std;
int main(){
	for(int i=1125,j=1727;i>0;){
		cout<<i<<' '<<i+1<<' '<<j<<' '<<j+1<<endl;
		i-=2;j+=2;
	}
	return 0;
}

 

 


2.网友年龄

某君新认识一网友。
当问及年龄时,他的网友说:
“我的年龄是个2位数,我比儿子大27岁,
如果把我的年龄的两位数字交换位置,刚好就是我儿子的年龄”

请你计算:网友的年龄一共有多少种可能情况?

提示:30岁就是其中一种可能哦.

请填写表示可能情况的种数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

#include<iostream>
using namespace std;
int main(){
	int cnt=0,tmp;
	for(int i=27;i<=99;i++){
		tmp=(i%10)*10+i/10;
		if(i-tmp==27){
			cout<<i<<' '<<tmp<<endl;
			cnt++;
		}
	}
	cout<<cnt;
	return 0;
}

 

 

3.圆周率


历史上有许多计算圆周率pai的公式,其中,格雷戈里和莱布尼茨发现了下面的公式:

pai = 4*(1-1/3+1/5-1/7 ....)

参见【图1.png】

这个公式简单而优美,但美中不足,它收敛的太慢了。
如果我们四舍五入保留它的两位小数,那么:

累积了1项和是:4.00
累积了2项和是:2.67
累积了3项和是:3.47
。。。

请你写出它累积了100项的和是多少(四舍五入到小数后两位)。

注意:只填写该小数本身,不要填写任何多余的说明或解释文字。

#include<iostream>
#include<cstdio>
using namespace std;
int main(){
	int cnt=0;
	double PI=0;
	for(int mu=1,flag=1;cnt!=100;mu+=2){
		PI+=1.0*flag*4/mu;
		cnt++;
		flag=-flag;
		printf("%d: %.2lf\n",cnt,PI);
	}
	printf("%d: %.2lf\n",cnt,PI);
	return 0;
}

 

 

4.平方怪圈

如果把一个正整数的每一位都平方后再求和,得到一个新的正整数。
对新产生的正整数再做同样的处理。

如此一来,你会发现,不管开始取的是什么数字,
最终如果不是落入1,就是落入同一个循环圈。

请写出这个循环圈中最大的那个数字。

请填写该最大数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int cnt=0;
void deal(ll n){
	if(cnt==30) return;
	int sum=0;
	while(n){
		sum+=(n%10)*(n%10);
		n/=10;
	}
	cout<<++cnt<<": "<<sum<<endl;
	deal(sum);
}
int main(){
	for(int i=1;i<=1000;i++){
		cout<<"NO."<<i<<":"<<endl;
		cnt=0;
		deal(i);
		cout<<endl;
	}
	return 0;
}

 

 

5.打印方格

小明想在控制台上输出 m x n 个方格。
比如 10x4的,输出的样子是:
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+

(如果显示有问题,可以参见【图1.jpg】)

以下是小明写的程序,请你分析其流程,填写划线部分缺少的代码。


#include <stdio.h>

//打印m列,n行的方格 
void f(int m, int n)
{
    int row;
    int col;
    
    for(row=0; row<n; row++){
        for(col=0; col<m; col++) printf("+---");
        printf("+\n");
        for(col=0; col<m; col++) printf("|   ");
        printf("|\n");        
    }
    
    printf("+");
    for(col=0; col<m; col++) printf("---+");   //填空
    printf("\n");
}

int main()
{
    f(10,4);
    return 0;
}

 

 

6.搭积木

小明最近喜欢搭数字积木,
一共有10块积木,每个积木上有一个数字,0~9。

搭积木规则:
每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
最后搭成4层的金字塔形,必须用完所有的积木。

下面是两种合格的搭法:

   0
  1 2
 3 4 5
6 7 8 9

   0
  3 1
 7 5 2
9 8 6 4    

请你计算这样的搭法一共有多少种?

请填表示总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
bool judge(int i,int j){
	return (a[i]<a[j]?1:0);
}
int main(){
	int cnt=0;
	do{
		if(!judge(0,1)||!judge(0,2)) continue;
		if(!judge(1,3)||!judge(1,4)||!judge(2,4)||!judge(2,5)) continue;
		if(!judge(3,6)||!judge(3,7)||!judge(4,7)||!judge(4,8)||!judge(5,8)||!judge(5,9)) continue;
		cnt++;
	}while(next_permutation(a,a+10));
	cout<<cnt;
	return 0;
}

 

 


7.寒假作业

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
   (如果显示不出来,可以参见【图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

就算两种解法。(加法,乘法交换律后算不同的方案)
 
你一共找到了多少种方案?


请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

调皮的数组下标把我害惨了……
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int main(){
	int cnt=0;
	do{
		if(a[9]+a[10]!=a[11]) continue;
		if(a[6]-a[7]!=a[8]) continue;
		if(a[3]*a[4]!=a[5]) continue;
		if(a[0]==a[1]*a[2]) cnt++;
	}while(next_permutation(a,a+13));
	cout<<cnt;
	return 0;
} 
orz
#include<iostream>
using namespace std;
int a[13],vis[13];
int cnt=0;
void dfs(int step){
	if(step>3&&a[0]+a[1]!=a[2]) return;
	if(step>6&&a[3]-a[4]!=a[5]) return;
	if(step>9&&a[6]*a[7]!=a[8]) return;
	if(step>12&&a[9]==a[10]*a[11]){
		cnt++;
		return;
	}
	for(int i=0;i<13;i++){
		if(!vis[i]){
			vis[i]=1;
			a[step]=i+1;
			if(step<13) dfs(step+1);
			vis[i]=0;
		}
	}
}
int main(){
	dfs(0);
	cout<<cnt;
	return 0;
} 

 

 

 

 

8.冰雹数

任意给定一个正整数N,
如果是偶数,执行: N / 2
如果是奇数,执行: N * 3 + 1

生成的新的数字再执行同样的动作,循环往复。

通过观察发现,这个数字会一会儿上升到很高,
一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。

比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。

输入格式:
一个正整数N(N<1000000)
输出格式:
一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。

例如,输入:
10
程序应该输出:
52

再例如,输入:
100
程序应该输出:
9232

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

 错误题解,因为1可以到达4: 

        

#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
int main() {
	ll n,maxn,x;
	cin>>n;
	maxn=n;//初始化最大值为n
	for(ll i=1;i<=n;i++) {
		x=i;//取当前数字
		int flag=0;
		while(1) {
			if(x==1) flag++;
			if(x==1&&flag==2) break;//第二次出现1 跳出循环
			if(x%2==0) x/=2;
			else if(x%2==1) x=x*3+1;
			maxn=max(x,maxn);
		}
	}
	cout<<maxn;
	return 0;
}

 

 

 

9.交换瓶子

有N个瓶子,编号 1 ~ N,放在架子上。

比如有5个瓶子:
2 1 3 5 4

要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5

对于这么简单的情况,显然,至少需要交换2次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。

输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

例如,输入:
5
3 1 2 5 4

程序应该输出:
3

再例如,输入:
5
5 4 3 2 1

程序应该输出:
2

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

#include<iostream>
#include<cstdio>
using namespace std;
int a[10005],pos[10005];
int main() {
	int n,cnt=0,tmp;
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		pos[a[i]]=i;
	}
	for(int i=1;i<=n;i++){
		if(a[i]!=i){
			tmp=a[i];
			a[i]=a[pos[i]];
			a[pos[i]]=tmp;
			cnt++;
		}
	}
	cout<<cnt;
	return 0;
}

 

 

10.密码脱落(最长公共子序列+非连续)

X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

输入一行,表示现在看到的密码串(长度不大于1000)
要求输出一个正整数,表示至少脱落了多少个种子。

例如,输入:
ABCBA
则程序应该输出:
0

再例如,输入:
ABDCDCBABC
则程序应该输出:
3

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

解法:求该字串与其反转字符串非连续的最长公共子序列

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int dp[1005][1005];
int main() {
	string s1,s2;
	cin>>s1;
	int len=s1.size();
	s2=s1;
	reverse(s1.begin(),s1.end());
	for(int i=1; i<=len; i++) //注意下标从1~len,因为下文要i-1,j-1什么的
		for(int j=1; j<=len; j++)
			if(s1[i]==s2[j]) dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
			else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
	cout<<len-dp[len][len];
	return 0;
}

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值