蓝桥杯2013年省赛C/C++大学组 C/C++

1、题目标题: 猜年龄
美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。
一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:
“我年龄的立方是个4位数。我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。”
请你推算一下,他当时到底有多年轻。
通过浏览器,直接提交他那时的年龄数字。
注意:不要提交解答过程,或其它的说明文字。

能偷懒绝不写代码,打开WINDOWS自带的计算器从11开始试就是了

2、题目标题: 排它平方数
小明正看着 203879 这个数字发呆。
原来,203879 * 203879 = 41566646641
这有什么神奇呢?仔细观察,203879 是个6位数,并且它的每个数位上的数字都是不同的,并且它平方后的所有数位上都不出现组成它自身的数字。
具有这样特点的6位数还有一个,请你找出它!
再归纳一下筛选要求:
1. 6位正整数
2. 每个数位上的数字不同
3. 其平方数的每个数位不含原数字的任何组成数位
答案是一个6位的正整数。
请通过浏览器提交答案。
注意:只提交另一6位数,题中已经给出的这个不要提交。
注意:不要书写其它的内容(比如:说明性的文字)。

反正暴力就是了,写好程序让机器跑着,过会看结果就是了,也可以先试一下给出的203879是不是能运行出来再继续跑,答案639172

#include<bits/stdc++.h>
using namespace std;
int num[10];
int main()
{
	int flag;
	unsigned long long  temp,i;
	for(i=203880;i<=999999;i++)
	{
		flag=0;
		memset(num,0,sizeof(num));
		cout<<i<<endl;
		temp=i*i;
		int t=i;
		while(t>0)
		{
			int tt=t%10;
			t/=10;
			if(num[tt]==0)
			num[tt]++;
			else
			flag=1;
			
			if(flag)
			break;
		}
		if(flag) continue;
		while(temp>0)
		{
			int tt=temp%10;
			if(num[tt]==1)
			{
				flag=1;
				break;
			}
			temp/=10;
			
		}
		if(flag)continue;
		else 
		{
			cout<<i<<endl;
			getchar();
			return 0;
		} 
	}
	
}

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

写成汉字都是迷惑的,把汉字化成数字然后DFS求方案数就可以了,答案35

#include<bits/stdc++.h>
using namespace std;
int Map[4][5]={0,1,2,3,4,1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};
int dir[4][2]={1,0,0,1,};
int vis[4][5];
int ans=0;
void dfs(int x,int y)
{
	if(x==3&&y==4)
	{
		ans++;
		return;
	}
	for(int i=0;i<2;i++)
	{
		int xx=x+dir[i][0];
		int yy=y+dir[i][1];
		if(xx<0||yy<0||xx>3||yy>4)continue;
		if(vis[xx][yy])continue;
		vis[xx][yy]=1;
		dfs(xx,yy);
		vis[xx][yy]=0;
	}
	
}
int main()
{
	memset(vis,0,sizeof(vis));
	vis[0][0]=1;
	dfs(0,0);
	cout<<ans<<endl;
	return 0;
}

4、标题: 幻方填空
幻方是把一些数字填写在方阵中,使得行、列、两条对角线的数字之和都相等。
欧洲最著名的幻方是德国数学家、画家迪勒创作的版画《忧郁》中给出的一个4阶幻方。
他把1,2,3,…16 这16个数字填写在4 x 4的方格中。
如图p1.jpg所示,即:
在这里插入图片描述
16 ? ? 13
? ? 11 ?
9 ? ? *
? 15 ? 1
表中有些数字已经显露出来,还有些用?和*代替。
请你计算出? 和 * 所代表的数字。并把 * 所代表的数字作为本题答案提交。

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

这题没有写代码,猜着手写的,想要填出幻方,一定要尽量让一个横行或者竖列或者对角线处于一个平均的大小,
也就是尽可能往34上凑,本着这个原则填就好了,答案是12

5、题目标题:公约数公倍数
我们经常会用到求两个整数的最大公约数和最小公倍数的功能。
下面的程序给出了一种算法。
函数 myfunc 接受两个正整数a,b
经过运算后打印出 它们的最大公约数和最小公倍数。
此时,调用 myfunc(15,20)
将会输出:
5
60

// 交换数值
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}

void myfunc(int a, int b)
{
int m,n,r;
if(a<b) swap(&a,&b);
m=a;n=b;r=a%b;
while(r!=0)
{
a=b;b=r;
r=a%b;
}
printf("%d\n",b); // 最大公约数
printf("%d\n", ____________________________________); // 最小公倍数
}

请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

读懂代码就能写出来,答案是m*n/b

6、标题:逆波兰表达式
正常的表达式称为中缀表达式,运算符在中间,主要是给人阅读的,机器求解并不方便。
例如:3 + 5 * (2 + 6) - 1
而且,常常需要用括号来改变运算次序。
相反,如果使用逆波兰表达式(前缀表达式)表示,上面的算式则表示为:
- + 3 * 5 + 2 6 1
不再需要括号,机器可以用递归的方法很方便地求解。
为了简便,我们假设:

  1. 只有 + - * 三种运算符
  2. 每个运算数都是一个小于10的非负整数

下面的程序对一个逆波兰表示串进行求值。
其返回值为一个结构:其中第一元素表示求值结果,第二个元素表示它已解析的字符数。

struct EV
{
int result; //计算结果
int n; //消耗掉的字符数
};

struct EV evaluate(char* x)
{
struct EV ev = {0,0};
struct EV v1;
struct EV v2;

if(*x==0) return ev;

if(x[0]>=‘0’ && x[0]<=‘9’){
ev.result = x[0]-‘0’;
ev.n = 1;
return ev;
}

v1 = evaluate(x+1);
v2 = _____________________________; //填空位置

if(x[0]’+’) ev.result = v1.result + v2.result;
if(x[0]
’*’) ev.result = v1.result * v2.result;
if(x[0]==’-’) ev.result = v1.result - v2.result;
ev.n = 1+v1.n+v2.n;

return ev;
}

请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

读代码可以看出来,代码的意思是说递归到读到数字为止,这时记录占用的字符数,再找下一个数
也就是说V1就是找到的第一个数,第二个数要在V1后继续寻找,那么就容易知道答案为evaluate(x+v1.n+1)

7、标题:核桃的数量

小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:

  1. 各组的核桃数量必须相同
  2. 各组内必须能平分核桃(当然是不能打碎的)
  3. 尽量提供满足1,2条件的最小数量(节约闹革命嘛)

程序从标准输入读入:
a b c
a,b,c都是正整数,表示每个组正在加班的人数,用空格分开(a,b,c<30)

程序输出:
一个正整数,表示每袋核桃的数量。

例如:
用户输入:
2 4 5

程序输出:
20

再例如:
用户输入:
3 1 1

程序输出:
3

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

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

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

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

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

看着麻烦,就是找输入的三个数的最小公倍数,直接把上个填空题的代码改动一下就好了

#include<bits/stdc++.h>
using namespace std;
void swap(int *a,int *b)
{
   int temp;
   temp=*a;
   *a=*b;
   *b=temp;
}

void myfunc(int a, int b,int c)
{
   int m,n,r;  
   if(a<b) swap(&a,&b);
   m=a;n=b;r=a%b;
   while(r!=0)
   {
    a=b;b=r;
    r=a%b;
   }
	int d=m*n/b;
	if(d<c) swap(&d,&c);
	m=d;n=c;r=d%c;
	while(r!=0)
	{
		d=c;c=r;
		r=d%c;
	 } 
   printf("%d\n", m*n/c);  
}
int main()
{
	int a,b,c;
	cin>>a>>b>>c;
	myfunc(a,b,c);
}

8、题目标题:打印十字图

小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示(可参见p1.jpg)

                 $$$$$$$$$$$$$
                 $           $
               $$$ $$$$$$$$$ $$$
               $   $       $   $
               $ $$$ $$$$$ $$$ $
               $ $   $   $   $ $
               $ $ $$$ $ $$$ $ $
               $ $ $   $   $ $ $
               $ $ $ $$$$$ $ $ $
               $ $ $   $   $ $ $
               $ $ $$$ $ $$$ $ $
               $ $   $   $   $ $
               $ $$$ $$$$$ $$$ $
               $   $       $   $
               $$$ $$$$$$$$$ $$$
                 $           $
                 $$$$$$$$$$$$$


对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。

为了能准确比对空白的数量,程序要求对行中的空白以句点(.)代替。

输入格式:
一个正整数 n (n<30) 表示要求打印图形的层数

输出:
对应包围层数的该标志。

例如:
用户输入:
1
程序应该输出:

..$$$$$..
..$...$..
$$$.$.$$$
$...$...$
$.$$$$$.$
$...$...$
$$$.$.$$$
..$...$..
..$$$$$..

再例如:
用户输入:
3
程序应该输出:

..$$$$$$$$$$$$$..
..$...........$..
$$$.$$$$$$$$$.$$$
$...$.......$...$
$.$$$.$$$$$.$$$.$
$.$...$...$...$.$
$.$.$$$.$.$$$.$.$
$.$.$...$...$.$.$
$.$.$.$$$$$.$.$.$
$.$.$...$...$.$.$
$.$.$$$.$.$$$.$.$
$.$...$...$...$.$
$.$$$.$$$$$.$$$.$
$...$.......$...$
$$$.$$$$$$$$$.$$$
..$...........$..
..$$$$$$$$$$$$$..

请仔细观察样例,尤其要注意句点的数量和输出位置。

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

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

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

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

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

想打死出题人系列,不难,就是单纯的麻烦,考这种题有什么意思

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	scanf("%d",&n);
	char Map[5+4*n][5+4*n];
	for(int i=0;i<5+4*n;i++)
		for(int j=0;j<5+4*n;j++)
			Map[i][j]='.';
			
	//画框
	for(int i=0;i<n;i++)
	{
		for(int j=2*(n-i-1)+2;j<=2*(n-i+1)+2+4*i;j++)
		{
			Map[2*(n-i)-2][j]='$';	
			Map[2*(n-i)+2+4*(i+1)][j]='$';
			Map[j][2*(n-i)-2]='$';
			Map[j][2*(n-i)+2+4*(i+1)]='$';
			
			Map[2*(n-i)][2*(n-i)]='$';
			Map[2*(n-i)-1][2*(n-i)]='$';
			Map[2*(n-i)][2*(n-i)-1]='$';
			
			Map[2*(n+i+1)+2][2*(n+i+1)+2]='$';
			Map[2*(n+i+1)+3][2*(n+i+1)+2]='$';
			Map[2*(n+i+1)+2][2*(n+i+1)+3]='$';
			
			Map[2*(n-i)][2*(n+i+1)+2]='$';
			Map[2*(n-i)-1][2*(n+i+1)+2]='$';
			Map[2*(n-i)][2*(n+i+1)+3]='$';
			
			Map[2*(n+i+1)+2][2*(n-i)]='$';
			Map[2*(n+i+1)+3][2*(n-i)]='$';
			Map[2*(n+i+1)+2][2*(n-i)-1]='$';
		}	 
	} 		
	//划十字		
	for(int i=2*n;i<2*n+5;i++)
		Map[2*n+2][i]='$';
	for(int i=2*n;i<2*n+5;i++)
		Map[i][2*n+2]='$';

	//输出 
	for(int i=0;i<5+4*n;i++)
	{
		for(int j=0;j<5+4*n;j++)
			printf("%c",Map[i][j]); 
		printf("\n");
	}
		
	return 0;
}

9、标题:剪格子

如图p1.jpg所示,3 x 3 的格子中填写了一些整数。
在这里插入图片描述
我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60。

本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0

程序输入输出格式要求:

程序先读入两个整数 m n 用空格分割 (m,n<10)
表示表格的宽度和高度
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000
程序输出:在所有解中,包含左上角的分割区可能包含的最小的格子数目。

例如:
用户输入:
3 3
10 1 52
20 30 1
1 2 3

则程序输出:
3

再例如:
用户输入:
4 3
1 1 1 1
1 30 80 2
1 1 1 100

则程序输出:
10

(参见p2.jpg)

在这里插入图片描述
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 5000ms

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

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

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

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

一道DFS,需要注意的是如果方案不为一时要选择左上角的那个,这种情况需要在DFS的递归终点处做一下修改,如果方案数不唯一了,就优先选择左上角走过的,就是VIS[0][0]=1的那个

#include<stdio.h>
#include<iostream>
#include<memory.h>
using namespace std;
int Map[15][15];
int vis[15][15];
int m,n,flag=0;
long long int cnt1=0,cnt2=0;
int ans=0,A=9999999;
int dir[4][2]={1,0,-1,0,0,1,0,-1}; 
void dfs(int x,int y)
{
	if(cnt1==cnt2)
	{
		if(ans<A&&flag==0)
		A=ans,flag=1;
		
		if(flag==1&&ans<A)
		{
			if(vis[0][0])
				A=ans;
		}
		
	}
	for(int i=0;i<4;i++)
	{
		int tx=x+dir[i][0];
		int ty=y+dir[i][1];
		if(tx<0||ty<0||tx>=m||ty>=n)continue;
		if(vis[tx][ty])continue;
		
		vis[tx][ty]=1;
		cnt1-=Map[tx][ty];
		cnt2+=Map[tx][ty];
		ans++;
		dfs(tx,ty);
		ans--;
		cnt1+=Map[tx][ty];
		cnt2-=Map[tx][ty];
		vis[tx][ty]=0;
	}
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
			cin>>Map[i][j],cnt1+=Map[i][j];
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			vis[i][j]=1;
			cnt2=Map[i][j];
			cnt1-=Map[i][j];
			ans++;
			dfs(i,j);
			ans--;
			vis[i][j]=0;
			cnt1+=Map[i][j];
		}
	}
	cout<<A<<endl;
	return 0;
}

10、还有一道不会的,先挂上,像极了牛客网寒假算法训练营2里的一道题

标题:买不到的数目

小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)

要求输出:
一个正整数,表示最大不能买到的糖数

例如:
用户输入:
4 7
程序应该输出:
17

再例如:
用户输入:
3 5
程序应该输出:
7

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/weixin_43849505/article/details/86633724
今日推荐