蓝桥杯 结果填空题

一。黄金队列
    黄金分割数0.618与美学有重要的关系。舞台上报幕员所站的位置大约就是舞台宽度的0.618处,墙上的画像一般也挂在房间高度的0.618处,甚至股票的波动据说也能找到0.618的影子....
    黄金分割数是个无理数,也就是无法表示为两个整数的比值。0.618只是它的近似值,其真值可以通过对5开方减去1再除以2来获得,我们取它的一个较精确的近似值:0.618034
    有趣的是,一些简单的数列中也会包含这个无理数,这很令数学家震惊!
    1 3 4 7 11 18 29 47 .... 称为“鲁卡斯队列”。它后面的每一个项都是前边两项的和。
    如果观察前后两项的比值,即:1/3,3/4,4/7,7/11,11/18 ... 会发现它越来越接近于黄金分割数!
    你的任务就是计算出从哪一项开始,这个比值四舍五入后已经达到了与0.618034一致的精度。

    请写出该比值。格式是:分子/分母。比如:29/47


//简单暴力搜索

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    int a=1,b=3,c;
    for(int i=2;; i++)
    {
        c=a+b;
        a=b;
        b=c;
        if(fabs(a*1.0/b-0.618034)<=0.000001)
        {
            cout<<a<<"/"<<b<<endl;
            break;
        }
    }
    return 0;
}


二。巧排扑克牌

    小明刚上小学,学会了第一个扑克牌“魔术”,到处给人表演。魔术的内容是这样的:
    他手里握着一叠扑克牌:A,2,....J,Q,K 一共13张。他先自己精心设计它们的顺序,然后正面朝下拿着,开始表演。
    只见他先从最下面拿一张放到最上面,再从最下面拿一张翻开放桌子上,是A;然后再从最下面拿一张放到最上面,再从最下面拿一张翻开放桌子上,是2;......如此循环直到手中只有一张牌,翻开放桌子上,刚好是K。
    这时,桌上牌的顺序是:A,2,3,4,5,6,7,8,9,10,J,Q,K
    请你计算一下,小明最开始的时候手里牌的顺序是怎样的。
    把结果写出来,逗号分割,小明“魔术”开始时,最下面的那张牌输出为第一个数据。
    考场不提供扑克牌,你只能用计算机模拟了,撕碎草稿纸模拟扑克属于作弊行为!另外,你有没有把录像倒着放过?很有趣的!回去试试!

//规律是从头开始数,每次都是每数二个有效位置填数

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    int result[13],init[13]= {14,2,3,4,5,6,7,8,9,10,11,12,13};
    int visited[13]= {0};
    int i=0,j=0;
    int cnt=0;
    while(i<13)
    {
        if(visited[j]==0)
            cnt++;
        if(cnt==2)
        {
            result[j]=init[i++];
            visited[j]=1;
            cnt=0;
        }
        j++;
        j=j%13;
    }
    for(i=0; i<13; i++)
    {
        if(result[i]==11)
            cout<<(i==12?"J":"J, ");
        else if(result[i]==12)
            cout<<(i==12?"Q":"Q, ");
        else if(result[i]==13)
            cout<<(i==12?"K":"K, ");
        else if(result[i]==14)
            cout<<(i==12?"A":"A, ");
        else
            cout<<result[i]<<(i==12?"":", ");
    }
    cout<<endl;
    return 0;
}

三。微生物增值

    假设有两种微生物 X 和 Y
    X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
    一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y。
    现在已知有新出生的 X=10, Y=89,求60分钟后Y的数目。
    如果X=10,Y=90  呢?
    本题的要求就是写出这两种初始条件下,60分钟后Y的数目。
    题目的结果令你震惊吗?这不是简单的数字游戏!真实的生物圈有着同样脆弱的性质!也许因为你消灭的那只 Y 就是最终导致 Y 种群灭绝的最后一根稻草!
    请忍住悲伤,把答案写在“解答.txt”中,不要写在这里!

思路:由题中x每3分钟分裂一次,y每2分钟分裂一次,所以我们知道以6分钟为界进行一步步分析。

在0.5分钟时,x=x,y=y-x (x未变y被吃)         在1.5分钟时x=x,y=y-x  (x未变y被吃) 故在前1.5分钟内x值没有变,而y=y-2*x

在2分钟时x=x,y=y+y  (x未变y增殖)               在2.5分钟时x=x,y=y-x  (x未变y被吃)                        在3分钟时 x=x+x,y=y   (x增殖y没变)              

在3.5分钟时x=x,y=y-x(x未变y被吃)               在4分钟时x=x,y=y+y(x未变y增殖)          在4.5分钟与5.5分钟 x没变y被吃了两次         在6分钟x=x+x,y=y+y两者都在增殖

以后的过程就是在重复上述过程

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    long long x,y;
    cin>>x>>y;
    for(int t=6; t<=60; t=t+6)
    {
        if(y<=0)
            break;
        y=y-2*x;
        y=y+y;
        y=y-x;
        x=x+x;
        y=y-x;
        y=y+y;
        y=y-2*x;
        x=x+x;
        y=y+y;
    }
    cout<<(y<=0?0:y)<<endl;
    return 0;
}


四。比酒量

    有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复...... 直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。
    等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“......昨天,我正好喝了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”
    请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
    如果有多个可能的答案,请列出所有答案,每个答案占一行。
    格式是:人数,人数,...
    例如,有一种可能是:20,5,4,2,0


思路:

由题意可以知道总人数在5~20之间,最后船长喝倒的那一轮(第三轮)人数最少2个,是我们用暴力求解。第一层循环控制总人数,下面三层分别表示第一轮,第二轮,第三轮喝完后还剩下的人数。关键点是船长说他总共喝了1瓶,那么我们可以在每一轮用1除以该轮人数,然后相加最后分式 1/count+1/A+1/B+1/C==1 就对了。

#include <iostream>
using namespace std;
int lcm(int a,int b)
{
    int mul=a*b;
    while(a%b!=0)
    {
        int r=a%b;
        a=b;
        b=r;
    }
    return mul/b;
}

int main()
{
    for(int count=20; count>=5; count--)
        for(int A=count-1; A>=4; A--)
            for(int B=A-1; B>=3; B--)
                for(int C=B-1; C>=2; C--)
                {
                    int temp=lcm(count,A);
                    temp=lcm(temp,B);
                    temp=lcm(temp,C);
                    int Tcount=temp/count;
                    int TA=temp/A;
                    int TB=temp/B;
                    int TC=temp/C;
                    if(Tcount+TA+TB+TC==temp)
                        cout<<count<<" "<<A<<" "<<B<<" "<<C<<" 0"<<endl;
                }
    return 0;
}


五。古堡算式

    福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:
    ABCDE * ? = EDCBA
    他对华生说:“ABCDE应该代表不同的数字,问号也代表某个数字!”
    华生:“我猜也是!”
    于是,两人沉默了好久,还是没有算出合适的结果来。
    请你利用计算机的优势,找到破解的答案。
    把 ABCDE 所代表的数字写出来。


穷举法,注意A,B,C,D,E 代表的是不同的数字

#include <iostream>
using namespace std;
int main()
{
    for(int A=0; A<=9; A++)
        for(int B=0; B<=9; B++)
            for(int C=0; C<=9; C++)
                for(int D=0; D<=9; D++)
                    for(int E=0; E<=9; E++)
                        for(int x=0; x<=9; x++)
                        {
                            if(A!=B&&A!=C&&A!=D&&A!=E&&B!=C&&B!=D&&B!=E&&C!=D&&C!=E&&D!=E)
                            {
                                int left=A*10000+B*1000+C*100+D*10+E;
                                int right=E*10000+D*1000+C*100+B*10+A;
                                if(left*x==right)
                                    cout<<A<<B<<C<<D<<E<<endl;
                            }
                        }
    return 0;
}


六。奇怪的比赛

    某电视台举办了低碳生活大奖赛。题目的计分规则相当奇怪
    每位选手需要回答10个问题(其编号为1到10),越后面越有难度。答对的,当前分数翻倍;答错了则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。
    每位选手都有一个起步的分数为10分。
    某获胜选手最终得分刚好是100分,如果不让你看比赛过程,你能推断出他(她)哪个题目答对了,哪个题目答错了吗?
    如果把答对的记为1,答错的记为0,则10个题目的回答情况可以用仅含有1和0的串来表示。例如:0010110011 就是可能的情况。
    你的任务是算出所有可能情况。每个答案占一行。

思路:穷举法,每个题有2种选择,一共有2^10即1024种做法

#include <iostream>
using namespace std;
int main()
{
    int a[10]= {0};
    for(int t=0; t<1024; t++)
    {
        int n=10;
        for(int i=0; i<10; i++)
        {
            if(a[i]==0)
                n=n-(i+1);
            else
                n=n+n;
        }
        if(n==100)
        {
            for(int i=0; i<10; i++)
                cout<<a[i]<<" ";
            cout<<endl;
        }
        a[0]++;
        for(int i=0; i<9; i++)
        {
            if(a[i]==1)
                break;
            else
            {
                a[i]=0;
                a[i+1]++;
            }
        }
    }
    return 0;
}

思路:递归

#include <iostream>
using namespace std;
int vis[10];
void cal(int n,int t)
{
    if(t==10)
    {
        if(n==100)
        {
            for(int i=0; i<10; i++)
                cout<<vis[i]<<" ";
            cout<<endl;
        }
        return ;
    }
    vis[t]=1;
    cal(2*n,t+1);
    vis[t]=0;
    cal(n-(t+1),t+1);
}
int main()
{
    cal(10,0);
    return 0;
}


七。硬币方案

有50枚硬币,可能包括4种类型:1元,5角,1角,5分。
已知总价值为20元。求各种硬币的数量。
比如:2,34,6,8 就是一种答案。
而 2,33,15,0 是另一个可能的答案,显然答案不唯一。
你的任务是确定类似这样的不同的方案一共有多少个(包括已经给出的2个)?
直接提交该数字,不要提交多余的内容。

思路:总共50枚硬币,所以四层循环都为0~50,且单位统一化成分

#include <iostream>
using namespace std;
int main()
{
    int sum=20*100,k=0;
    for(int i=0; i<=50; i++)
        for(int j=0; j<=50; j++)
            for(int m=0; m<=50; m++)
                for(int n=0; n<=50; n++)
                {
                    if(i*100+j*50+m*10+n*5==sum&&i+j+m+n==50)
                        k++;
                }
    cout<<k<<endl;
    return 0;
}


八。4—1凑算式

看这个算式:
☆☆☆ + ☆☆☆ = ☆☆☆
如果每个五角星代表 1 ~ 9 的不同的数字。
这个算式有多少种可能的正确填写方法?
173 + 286 = 459
295 + 173 = 468
173 + 295 = 468
183 + 492 = 675
以上都是正确的填写法!
注意:
111 + 222 = 333 是错误的填写法!
因为每个数字必须是不同的! 
也就是说:1~9中的所有数字,每个必须出现且仅出现一次!
注意:
不包括数字“0”!
注意:
满足加法交换率的式子算两种不同的答案。
所以答案肯定是个偶数!
注意:
只要求计算不同的填法的数目
不要求列出所有填写法
更不要求填写源代码!

#include <iostream>
using namespace std;
int N=0;
void cal(int a[],int k)
{
    if(k==9)
    {
        int x=a[0]*100+a[1]*10+a[2];
        int y=a[3]*100+a[4]*10+a[5];
        int z=a[6]*100+a[7]*10+a[8];
        if(x+y==z) N++;
        return;
    }
    //列举第k位的所有情况,交换法
    for(int i=k; i<=9; i++)
    {
        {
            int t=a[k];    //交换
            a[k]=a[i];
            a[i]=t;
        }
        cal(a, k+1);
        {
            int t=a[k];    //交换,回退
            a[k]=a[i];
            a[i]=t;
        }
    }
}
int main()
{
    int a[9]= {1,2,3,4,5,6,7,8,9};
    cal(a,0);
    cout<<N<<endl;
    return 0;
}


九。运动员分组

有N个人参加100米短跑比赛。跑道为8条。程序的任务是按照尽量使每组的人数相差最少的原则分组。

例如:

N=8时,分成1组即可。

N=9时,分成2组:一组5人,一组4人。

N=25时,分4组:7、6、6、6。

请编程计算分组数字。要求从键盘输入一个正整数(1~100之间,不必考虑输入错误的情况),表示参赛的人数。程序输出每个组的人数。从大到小顺序输出,每个数字一行。

比如,用户输入:25

程序输出:

7

6

6

6


#include <iostream>
using namespace std;
int main()
{
    int N,n;
    cin>>N;
    if(N%8!=0) n=N/8+1;
    else n=N/8;
    int *a=new int[n];
    for(int i=0; i<n; i++)
        a[i]=N/n;
    for(int i=0; i<N%8; i++)
        a[i]++;
    for(int i=0; i<n; i++)
        cout<<a[i]<<endl;
    return 0;
}


10.取球博弈

    今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。
    我们约定:
    每个人从盒子中取出的球的数目必须是:1,3,7或者8个。
    轮到某一方取球时不能弃权!
    A先取球,然后双方交替取球,直到取完。
    被迫拿到最后一个球的一方为负方(输方)
    请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?
    程序运行时,从标准输入获得数据,其格式如下:
    先是一个整数n(n<100),表示接下来有n个整数。然后是n个整数,每个占一行(整数<10000),表示初始球数。
    程序则输出n行,表示A的输赢情况(输为0,赢为1)。
    例如,用户输入:
    4
    1
    2
   10
   18
   则程序应该输出:
   0
   1
  1
  0

#include <iostream>
using namespace std;
bool f(int n)
{
if(n==1) return false;
if(n>1&&f(n-1)==false)return true;
if(n>3&&f(n-3)==false)return true;
if(n>7&&f(n-7)==false)return true;
if(n>8&&f(n-8)==false)return true;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
    int n;
    cin>>n;
    cout<<f(n)<<endl;
    }
return 0;
}


11。罗马数字

    古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。之所以这样,不是因为发明表示法的人的智力的问题,而是因为一个宗教的原因,当时的宗教禁止在数字中出现0的概念!
    罗马数字的表示主要依赖以下几个基本符号:
    I  1
    V  5
    X  10
    L  50
    C  100
    D  500
    M  1000
    这里,我们只介绍一下1000以内的数字的表示法。
    单个符号重复多少次,就表示多少倍。最多重复3次。比如:CCC表示300  XX表示20,但150并不用LLL表示,这个规则仅适用于I X C M。
    如果相邻级别的大单位在右,小单位在左,表示大单位中扣除小单位。比如:IX表示9  IV表示4  XL表示40 更多的示例参见下表,你找到规律了吗?
I,1 
II,2
III,3
IV,4
V,5
VI,6
VII,7
VIII,8
IX,9 

X,10
XI,11
XII,12
XIII,13
XIV,14----------------------------
XV,15
XVI,16
XVII,17
XVIII,18
XIX,19
XX,20
XXI,21
XXII,22
XXIX,29
XXX,30
XXXIV,34
XXXV,35
XXXIX,39
XL,40
L,50
LI,51
LV,55
LX,60
LXV,65
LXXX,80
XC,90
XCIII,93
XCV,95
XCVIII,98
XCIX,99

C,100
CC,200
CCC,300
CD,400
D,500
DC,600
DCC,700
DCCC,800
CM,900
CMXCIX,999
    本题目的要求是:请编写程序,由用户输入若干个罗马数字串,程序输出对应的十进制表示。
    输入格式是:第一行是整数n,表示接下来有n个罗马数字(n<100)。以后每行一个罗马数字。罗马数字大小不超过999。
    要求程序输出n行,就是罗马数字对应的十进制数据。
    例如,用户输入:
3
LXXX
XCIII
DCCII

    则程序应该输出:
80
93
702

思路:从右往左计算,左大右小就加,左小右大就减

#include <iostream>
#include <string>
using namespace std;
int digit(char s)
{
    if(s=='I')return 1;
    if(s=='V')return 5;
    if(s=='X')return 10;
    if(s=='L')return 50;
    if(s=='C')return 100;
    if(s=='D')return 500;
    if(s=='M')return 1000;
}


int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        string str;
        cin>>str;
        int sum=0;
        sum=sum+digit(str[str.size()-1]);
        for(int i=str.size()-2; i>=0; i--)
        {
            if(digit(str[i])>=digit(str[i+1]))
                sum=sum+digit(str[i]);
            else
                sum=sum-digit(str[i]);
        }
        cout<<sum<<endl;
    }
    return 0;
}


12.上楼问题

每次上1个台阶或2个台阶。求上楼方案数。

#include <cstdio>  
#include <cmath>  
int step[50];  
int main()  
{  
    int n,m;  
    cin>>n;
    while(n--)  
    {  
        cin>>m;
        step[1] = 1;  
        step[2] = 2;  
        for(int i=3; i<m; i++)  
        {  
            step[i] = step[i-1] + step[i-2];  
        }  
        cout<<step[i-1]<<endl;
    }  
    return 0;  
}



你可能感兴趣的:(蓝桥杯 结果填空题)