历年蓝桥杯决赛题目汇总?
1、标题:填算式
请看下面的算式:
(ABCD - EFGH) * XY = 900
每个字母代表一个0~9的数字,不同字母代表不同数字,首位不能为0。
比如,(5012 - 4987) * 36 就是一个解。
请找到另一个解,并提交该解中 ABCD 所代表的整数。
请严格按照格式,通过浏览器提交答案。
注意:只提交 ABCD 所代表的整数,不要写其它附加内容,比如:说明性的文字。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int arr[10]={0,1,2,3,4,5,6,7,8,9};
void dfs(){
int a=arr[0]*1000+arr[1]*100+arr[2]*10+arr[3];
int b=arr[4]*1000+arr[5]*100+arr[6]*10+arr[7];
int c=arr[8]*10+arr[9];
int x=(a-b)*c;
if(x==900){
cout<<a<<" "<<b<<" "<<c<<" "<<endl;
}
}
int main(){
do{
dfs();
}while(next_permutation(arr,arr+10));
return 0;
}
答案:6048 5973 12
2、标题:骰子迷题
小明参加了少年宫的一项趣味活动:每个小朋友发给一个空白的骰子
(它的6个面是空白的,没有数字),要小朋友自己设计每个面写哪个数字。但有如下要求:
1. 每个面只能填写 0 至 8 中的某一个数字。
2. 不同面可以填写同样的数字,但6个面总和必须等于24。
填好后,小朋友可以用自己填写好数字的骰子向少年宫的两个机器人挑战----玩掷骰子游戏。
规则如下:
三方同时掷出自己的骰子,如果出现任何相同的数字,则三方都不计分。
如果三方数字都不同,则最小数字一方扣 1 分,最大数字一方加 1 分。
小明看到了两个机器人手中的骰子分别是:
0 0 0 8 8 8
1 1 4 5 6 7
请你替小明算一下,他如何填写,才能使自己得分的概率最大。
请提交小明应该填写的6个数字,按升序排列,数字间用一个空格分开。
如果认为有多个答案,提交字母序最小的那个方案。
请严格按照格式,通过浏览器提交答案。
注意:只提交一行内容,含有6个被空格分开的数字。不要写其它附加内容,比如:说明性的文字。
#include<bits/stdc++.h>
using namespace std;
int Max=0;
int a[]={0,0,0,8,8,8};
int b[]={1,1,4,5,6,7};
int c[6];
int temp[6];
void count(){
int sum=0;
for(int i=0;i<6;i++){//统计小明骰子同时大于两个机器人的次数
int ma=0,mb=0;
for(int j=0;j<6;j++){
for(int k=0;k<6;k++){
if(c[i]>a[j]&&c[i]>b[k]){
ma++;
}
}
}
sum+=ma;
}
if(sum>Max){
Max=sum;
for(int i=0;i<6;i++){
temp[i]=c[i];
}
}
}
void dfs(int cur,int sum,int step){
if(step==6){
if(sum==24){
count();
}
return;
}
for(int i=0;i<9;i++){
c[step]=i;
dfs(i,sum+i,step+1);
c[step]=0;
}
}
int main(){
dfs(0,0,0);
sort(temp,temp+6);
for(int i=0;i<6;i++){
cout<<temp[i]<<ends;
}
return 0;
}
答案:2 2 2 2 8 8
3、标题:埃及分数
古埃及曾经创造出灿烂的人类文明,他们的分数表示却很令人不解。
古埃及喜欢把一个分数分解为类似: 1/a + 1/b 的格式。
这里,a 和 b 必须是不同的两个整数,分子必须为 1
比如,2/15 一共有 4 种不同的分解法(姑且称为埃及分解法):
1/8 + 1/120
1/9 + 1/45
1/10 + 1/30
1/12 + 1/20
那么, 2/45 一共有多少个不同的埃及分解呢(满足加法交换律的算同种分解)?
请直接提交该整数(千万不要提交详细的分解式!)。
请严格按照要求,通过浏览器提交答案。
注意:只提交分解的种类数,不要写其它附加内容,比如:说明性的文字
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
if(b==0)
return a;
else
return gcd(b,a%b);
}
int main(){
int ans=0;
for(int i=1;i<=10000;i++){
for(int j=i+1;j<+10000;j++){
int a=i+j,b=i*j;
int t=gcd(a,b);
a=a/t,b=b/t;
if(a==2&&b==45){
cout<<i<<" "<<j<<endl;
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}
答案:7
4、标题:约数倍数选卡片
闲暇时,福尔摩斯和华生玩一个游戏:
在N张卡片上写有N个整数。两人轮流拿走一张卡片。
要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数。
例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括:
1,2,3, 6,12,18,24 ....
当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方。
请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,
怎样选择才能保证必胜!
当选多个数字都可以必胜时,输出其中最小的数字。如果无论如何都会输,则输出-1。
输入数据为2行。第一行是若干空格分开的整数(每个整数介于1~100间),
表示当前剩余的所有卡片。
第二行也是若干空格分开的整数,表示可以选的数字。
当然,第二行的数字必须完全包含在第一行的数字中。
程序则输出必胜的招法!!
例如:
用户输入:
2 3 6
3 6
则程序应该输出:
3
再如:
用户输入:
1 2 2 3 3 4 5
3 4 5
则程序应该输出:
4
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型(千万不要混淆c和cpp)。
真的发现dotcpp网站跟蓝桥杯练习系统上面有问题,一模一模的答案在两个网站上面测试结果不一样,保险起见,还是用下面这种方法吧(我猜测应该是测试用例的数据不同,那么应该依照蓝桥杯练习系统按理来说应该标准一点,但是我发现有的代码在练习系统上拿满分,但是在dotcpp上面却过不了.......em...不知道该说什么?
#include<bits/stdc++.h>
using namespace std;
int card[101];
int arr[101];
bool flag=true;
int mm=101;
vector<int> table[101];
int dfs(int x){
for(int i=table[x].size()-1;i>=0;i--){
//table[x][i]里面存放的是x的约数和倍数
if(card[table[x][i]]){
card[table[x][i]]--;
int t=dfs(table[x][i]);
card[table[x][i]]++;
if(t==-1)//这里不是很容易理解...
return 1;//则对B来说是必败态,然后一直回溯,直到看第一个人是必胜还是必败
}
}
return -1;//说明上个人(假设这个人为A)拿走了x之后,则下个人(B)无牌可取,那么对A来说是必胜态
}
int main(){
int x;
while(cin>>x){
card[x]++;//因为我们不知道 剩余卡片有多少张,但是直到牌最大为100,因此统计每个面值的牌有多少张
if(cin.get()=='\n')
break;
}
while(cin>>x){
arr[x]++;//这里也是同理,统计可选的牌的张数和面值
if(cin.get()=='\n')
break;
}
for(int i=0;i<101;i++){
if(card[i]){//如果有这张牌
card[i]--;//假设拿走这张牌
for(int j=0;j<101;j++){
if(card[j]&&(i%j==0||j%i==0)){
table[i].push_back(j);//记录拿走这张牌后,在剩余的牌面中的约数和倍数
}
}
card[i]++;
}
}
for(int i=0;i<101;i++){
if(arr[i]){//如果这张牌可选
card[i]--;//就拿走它
int t=dfs(i);//然后判断拿走这张牌是必胜还是必败
if(t==-1){//必胜
mm=min(mm,i);
flag=false;
}
card[i]++;//回溯
}
}
if(flag)
cout<<"-1"<<endl;
else
cout<<mm<<endl;
return 0;
}
5、标题:网络寻路
X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。
某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。
该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。
源地址和目标地址可以相同,但中间节点必须不同。
如图1所示的网络。
1 -> 2 -> 3 -> 1 是允许的
1 -> 2 -> 1-> 2 或者 1->2->3->2 都是非法的。
输入数据的第一行为两个整数N M,分别表示节点个数和
连接线路的条数(1<=N<=10000; 0<=M<=100000)。
接下去有M行,每行为两个整数 u 和 v,表示节点u 和 v 联通(1<=u,v<=N , u!=v)。
输入数据保证任意两点最多只有一条边连接,
并且没有自己连自己的边,即不存在重边和自环。
输出一个整数,表示满足要求的路径条数。
例如:
用户输入:
3 3
1 2
2 3
1 3
则程序应该输出:
6
再例如:
用户输入:
4 4
1 2
2 3
3 1
1 4
则程序应该输出:
10
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型(千万不要混淆c和cpp)。
#include<bits/stdc++.h>
using namespace std;
#define M 100005
int m,n;
int arr[M];//记录了点数
vector<int> v[M];
int vis[M];
int ans=0;
void dfs(int f,int beg,int step){
vis[f]=1;//将第一个点标记
if(step==4){
ans++;
return;
}
for(int i=0;i<v[beg].size();i++){
int k=v[beg][i];
if(!vis[k]){
vis[k]=1;
dfs(f,k,step+1);
vis[k]=0;
}else if(step==3&&k==f){//最后一个点可以与起始点相同
dfs(f,k,step+1);
}
}
}
int main(){
cin>>n>>m;
int count=0;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
if(!vis[a]) vis[a]=1,arr[count++]=a;
if(!vis[b]) vis[b]=1,arr[count++]=b;
v[a].push_back(b);
v[b].push_back(a);
}
for(int i=0;i<count;i++){
memset(vis,0,sizeof(vis));
dfs(arr[i],arr[i],1);
}
cout<<ans<<endl;
return 0;
}
6、
标题:车轮轴迹
栋栋每天骑自行车回家需要经过一条狭长的林荫道。道路由于年久失修,变得非常不平整。虽然栋栋每次都很颠簸,但他仍把骑车经过林荫道当成一种乐趣。
由于颠簸,栋栋骑车回家的路径是一条上下起伏的曲线,栋栋想知道,他回家的这条曲线的长度究竟是多长呢?更准确的,栋栋想知道从林荫道的起点到林荫道的终点,他的车前轮的轴(圆心)经过的路径的长度。
栋栋对路面进行了测量。他把道路简化成一条条长短不等的直线段,这些直线段首尾相连,且位于同一平面内。并在该平面内建立了一个直角坐标系,把所有线段的端点坐标都计算好。
假设栋栋的自行车在行进的过程中前轮一直是贴着路面前进的。
图1给出了一个简单的路面的例子,其中蓝色实线为路面,红色虚线为车轮轴经过的路径。在这个例子中,栋栋的前轮轴从A点出发,水平走到B点,然后绕着地面的F点到C点(绕出一个圆弧),再沿直线下坡到D点,最后水平走到E点,在这个图中地面的坐标依次为:(0, 0), (2, 0), (4, -1), (6, -1),前轮半径为1.50,前轮轴前进的距离依次为:
AB=2.0000;弧长BC=0.6955;CD=1.8820;DE=1.6459。
总长度为6.2233。
图2给出了一个较为复杂的路面的例子,在这个例子中,车轮在第一个下坡还没下完时(D点)就开始上坡了,之后在坡的顶点要从E绕一个较大的圆弧到F点。这个图中前轮的半径为1,每一段的长度依次为:
AB=3.0000;弧长BC=0.9828;CD=1.1913;DE=2.6848;弧长EF=2.6224; FG=2.4415;GH=2.2792。
总长度为15.2021。
现在给出了车轮的半径和路面的描述,请求出车轮轴轨迹的总长度。
输入的第一行包含一个整数n和一个实数r,用一个空格分隔,表示描述路面的坐标点数和车轮的半径。
接下来n行,每个包含两个实数,其中第i行的两个实数x[i], y[i]表示描述路面的第i个点的坐标。
路面定义为所有路面坐标点顺次连接起来的折线。给定的路面的一定满足以下性质:
*第一个坐标点一定是(0, 0);
*第一个点和第二个点的纵坐标相同;
*倒数第一个点和倒数第二个点的纵坐标相同;
*第一个点和第二个点的距离不少于车轮半径;
*倒数第一个点和倒数第二个点的的距离不少于车轮半径;
*后一个坐标点的横坐标大于前一个坐标点的横坐标,即对于所有的i,x[i+1]>x[i]。
输出一个实数,四舍五入保留两个小数,表示车轮轴经过的总长度。
你的结果必须和参考答案一模一样才能得分。数据保证答案精确值的小数点后第三位不是4或5。
【样例输入1】
4 1.50
0.00 0.00
2.00 0.00
4.00 -1.00
6.00 -1.00
【样例输出1】
6.22
【样例说明1】
这个样例对应图1。
【样例输入2】
6 1.00
0.00 0.00
3.00 0.00
5.00 -3.00
6.00 2.00
7.00 -1.00
10.00 -1.00
【样例输出2】
15.20
【样例说明2】
这个样例对应图2
【数据规模与约定】
对于20%的数据,n=4;
对于40%的数据,n≤10;
对于100%的数据,4≤n≤100,0.5≤r≤20.0,x[i] ≤2000.0,-2000.0≤y[i] ≤2000.0。
资源约定:
峰值内存消耗 < 64M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型(千万不要混淆c和cpp)。
看到这道题目想弱弱的说,小明回家的路也太不好走了吧?