2014年蓝桥杯省赛(C/C++)B组

这次打的很不好,

首先第三题没读清题,“已知最后一次遇到的是花”这句话竟然没看到~~~

第五题没做出来,后来瞎猜猜出来的,通过这次我就发现,代码填空基本靠上下两句猜出答案。

第一题

标题:啤酒和饮料

    啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。

    我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。

    注意:答案是一个整数。请通过浏览器提交答案。

不要书写任何多余的内容(例如:写了饮料的数量,添加说明文字等)。

代码:

#include<cstdio>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;


int main()
{
    for(float i = 1; i <= 300.0; i++)
    {
        for(float j = i; j <= 999.0; j++)
        {
            if(fabs(i * 2.3 + j * 1.9 - 82.3) < 0.0001)
            {
                cout << i << "  " << j << endl;
            }
        }
    }
    return 0;
}
/*
3 10
5 6
7 8
10 11
*/

答案:11

第二题

标题:切面条

    一根高筋拉面,中间切一刀,可以得到2根面条。

    如果先对折1次,中间切一刀,可以得到3根面条。

    如果连续对折2次,中间切一刀,可以得到5根面条。

    那么,连续对折10次,中间切一刀,会得到多少面条呢?

答案是个整数,请通过浏览器提交答案。不要填写任何多余的内容。

答案:1025

第三题    李白打酒

    话说大诗人李白,一生好饮。幸好他从不开车。

    一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:

    无事街上走,提壶去打酒。

    逢店加一倍,遇花喝一斗。

    这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。

    请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。

注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。

代码:

#include<cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;


int arr[23] = {}, cnt = 0;
char book[234][245] = {};
void dfs(int shop, int flower, int step, int kk)
{
    if(shop == 5 && flower == 10)
    {
        if(step == 0 && arr[15] == 1)
        {
            cnt++;
            for(int i = 0; i < 15; i++)
            {
                book[cnt][i] = (arr[i] == 0 ? 'a' : 'b');
            }
            for(int i = 1; i < kk; i++)
            {
                if(arr[i])
                    cout << "b";
                else cout << "a";
            }
            cout << endl;
        }
        return;
    }
    if(shop > 5 || flower > 10)
    {
        return;
    }
    for(int i = 0; i <= 1; i++)
    {
        arr[kk] = i;
        if(i == 0)
        {
            dfs(shop + 1, flower, step * 2, kk + 1);
        }
        else dfs(shop, flower + 1, step - 1, kk + 1);
    }
}
int main(void)
{
    memset(arr, -1, sizeof(arr));
    dfs(0, 0, 2, 1);
    cout << cnt << endl;
    return 0;
}

答案:14

第四题

标题:史丰收速算

    史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算!

    速算的核心基础是:1位数乘以多位数的乘法。

    其中,乘以7是最复杂的,就以它为例。

    因为,1/7 是个循环小数:0.142857...,如果多位数超过 142857...,就要进1

    同理,2/7, 3/7, ... 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n

    下面的程序模拟了史丰收速算法中乘以7的运算过程。

    乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。

    乘以 7 的进位规律是:

142857... 1,

285714... 2,

428571... 3,

571428... 4,

714285... 5,

857142... 6

    请分析程序流程,填写划线部分缺少的代码。

241876844562801

//计算个位

int ge_wei(int a)

{

if(a % 2 == 0)

return (a * 2) % 10;

else

return (a * 2 + 5) % 10;

}

 

//计算进位

int jin_wei(char* p)

{

char* level[] = {

"142857",

"285714",

"428571",

"571428",

"714285",

"857142"

};

char buf[7];

buf[6] = '\0';

strncpy(buf,p,6);

int i;

for(i=5; i>=0; i--){

int r = strcmp(level[i], buf);

if(r<0) return i+1;

while(r==0){

p += 6;

strncpy(buf,p,6);

r = strcmp(level[i], buf);

if(r<0) return i+1;

______________________________;  //填空

}

}

return 0;

}

//多位数乘以7

void f(char* s)

{

int head = jin_wei(s);

if(head > 0) printf("%d", head);

char* p = s;

while(*p){

int a = (*p-'0');

int x = (ge_wei(a) + jin_wei(p+1)) % 10;

printf("%d",x);

p++;

}

printf("\n");

}

 

int main()

{

f("428571428571");

f("34553834937543");

f("142857142857142858");    ///这个是自己添加上去的,输出结果是1000000000000000006

return 0;

}

注意:通过浏览器提交答案。只填写缺少的内容,不要填写任何多余的内容(例如:说明性文字)

答案:if(r > 0) return i;   不是if(r == 0) return i;


第五题     打印图形

    小明在X星球的城堡中发现了如下图形和文字:

rank=3

 

rank=5

 

 

 

 

 

rank=6


    小明开动脑筋,编写了如下的程序,实现该图形的打印。

 

#define N 70

 

void f(char a[][N], int rank, int row, int col)

{

if(rank==1){

a[row][col] = '*';

return;

}

int w = 1;

int i;

for(i=0; i<rank-1; i++) w *= 2;

____________________________________________;

f(a, rank-1, row+w/2, col);

f(a, rank-1, row+w/2, col+w);

}

 

int main()

{

char a[N][N];

int i,j;

for(i=0;i<N;i++)

for(j=0;j<N;j++) a[i][j] = ' ';

f(a,6,0,0);

for(i=0; i<N; i++){

for(j=0; j<N; j++) printf("%c",a[i][j]);

printf("\n");

}

return 0;

}

 

 

    请仔细分析程序逻辑,填写缺失代码部分。

 

    通过浏览器提交答案。注意不要填写题目中已有的代码。也不要写任何多余内容(比如说明性的文字)

答案:f(a, rank - 1, row, col + w/2);

这题瞎猜的,别问我为什么

第六题    奇怪的分式

 

    上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:

    1/4 乘以 8/5

    小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png

    老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!

    对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?

    请写出所有不同算式的个数(包括题中举例的)。

    显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。

    但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!

注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。


代码:

#include<cstdio>
#include <cmath>
#include <algorithm>
using namespace std;


bool book[234] = {}, vis[243] = {};
int num[5] = {}, cnt = 0;
int rec[1234567][5] = {};
void dfs(int step)
{
    if(step == 5)
    {
        int bb[6] = {};
        int sum1 = num[1] * num[3] * (10 * num[2] + num[4]);
        int sum2 = num[2] * num[4] * (10 * num[1] + num[3]);
        if(sum1 == sum2)
        {
            cnt++;
            /*for(int i = 1; i <= 4; i++) bb[i] = num[i];
            sort(bb + 1, bb + 5);
            int i, j;
            for(i = 1; i <= cnt; i++)
            {
                for(j = 1; j <= 4; j++)
                {
                    if(rec[i][j] != bb[j]) break;
                }
                if(j > 4) break;
            }
            if(i > cnt)
            {
                ++cnt;
                for(int i = 1; i <= 4; i++) rec[cnt][i] = num[i];
            }*/
        }
        return;
    }
    for(int i = 1; i <= 9; i++)
    {
        if(step % 2 == 0 && i == num[step - 1]) continue;
            num[step] = i;
        dfs(step + 1);
        num[step] = -1;
    }
}
int main(void)
{
    dfs(1);
    printf("%d\n", cnt);
    return 0;
}

答案:14

第七题

 

标题:六角填数

 

    如图【1.png】所示六角形中,填入1~12的数字。

 

    使得每条直线上的数字之和都相同。

 

    图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?

 

请通过浏览器提交答案,不要填写多余的内容。

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;


int arr[14] = {}, sum[7] = {};
int main(void)
{
    for(int i = 1; i <= 12; i++)
    {
        arr[i] = i;
    }
    do{
        memset(sum, 0, sizeof(sum));
        for(int i = 1; i <= 4; i++)
            sum[1] += arr[i];
        sum[2] = arr[4] + arr[11] + arr[9] + arr[12];
        sum[3] = arr[1] + arr[6] + arr[8] + arr[12];
        sum[4] = arr[5] + arr[2] + arr[6] + arr[7];
        sum[5] = arr[5] + arr[3] + arr[11] + arr[10];
        for(int i = 7; i <= 10; i++)
            sum[6] += arr[i];
        int i;
        bool flag = true;
        for(i = 1; i <= 5; i++)
        {
            if(sum[i] != sum[i + 1])
            {
                flag = false;
                break;
            }
        }
        if(flag && arr[1] == 1 && arr[5] == 8 && arr[10] == 3)
        {
            for(int i = 1; i <= 12; i++)
            {
                printf("%d ", arr[i]);
            }
            printf("\n");
            for(int i = 1; i <= 6; i++)
            {
                printf("%d ", sum[i]);
            }
            printf("\n");
            printf("%d\n", arr[3]);
        }
    }while(next_permutation(arr + 1, arr + 13));


    return 0;
}

答案:10

第八题    蚂蚁感冒

    100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。

    每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。

    当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。

    这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。

    请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。

【数据格式】

    第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。

    接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。

 

    要求输出1个整数,表示最后感冒蚂蚁的数目。

 

例如,输入:

3

5 -2 8

程序应输出:

1

 

再例如,输入:

5

-10 8 -20 12 25

程序应输出:

3

 

资源约定:

峰值内存消耗 < 256M

CPU消耗  < 1000ms

 

 

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

 

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

 

注意: main函数需要返回0

注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

 

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

代码:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;

int left[123] = {}, right[123] = {};
int maps[123] = {}, cold[123] = {};
void getmaps(int ll, int rr, int dir, int dis)
{
    int l = 1, r = 1, cnt = 1;
    sort(left + 1, left + ll + 1);
    sort(right + 1, right + rr + 1);
    while(l <= ll && r <= rr)
    {
        while(l <= ll && left[l] <= right[r])
        {
            if(dir == 0 && left[l] == dis) cold[cnt] = 1;
            maps[cnt++] = 0;
            l++;
        }
        while(r <= rr && right[r] <= left[l])
        {
            if(dir == 1 && right[r] == dis) cold[cnt] = 1;
            maps[cnt++] = 1;
            r++;
        }
    }
    while(l <= ll)
    {
        maps[cnt++] = 0;
        l++;
    }
    while(r <= rr)
    {
        maps[cnt++] = 1;
        r++;
    }
}
void getcold(int n)
{
    int st = 1, ed = n, cc = 1;
    while(st < ed)
    {
        while(!maps[st])
        {
            st++;
        }
        while(maps[ed])
        {
            ed--;
        }
        for(int i = st; i <= ed; i++)
        {
            if(i < ed && maps[i] && !maps[i+1] && (cold[i] || cold[i + 1]))
            {
                cold[i + 1] = 1;
                cc++;
            }
            maps[i] = (maps[i] + 1) % 2;
        }
    }
    printf("%d\n", cc);
}
int main(void)
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        mem(maps, -1);
        int ll = 0, rr = 0, dir, dis;
        for(int i = 1; i <= n; i++)
        {
            int x;
            scanf("%d", &x);
            if(i == 1)
            {
                dir = x > 0 ? 1 : 0;
                dis = abs(x);
            }
            if(x > 0)
            {
                right[++rr] = x;
            }
            else
            {
                left[++ll] = abs(x);
            }
        }
        getmaps(ll, rr, dir, dis);
        getcold(n);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值