第六届蓝桥杯大赛个人赛省赛(软件类)C语言B组

1.奖券数目

**题目描述

有些人很迷信数字,比如带“4" 的数字,认为和“死"谐音,就觉得不吉利.
虽然这些说法纯属无穭之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码是5
位数(00009999), 要求其中不要出现带“4" 的号码,主办单位请你计算- -下,如果任
何两张奖券不重号,最多可发出奖券多少张.
请提交该数字(一个整数),不要写任何多余的内容或说明性文字.**

暴力解题,yyds!
52488张

#include <stdio.h>

main() {
    int sum = 0;
    for (int a = 1; a < 10; ++a) {
        for (int b = 0; b < 10; ++b) {
            for (int c = 0; c < 10; ++c) {
                for (int d = 0; d < 10; ++d) {
                    for (int e = 0; e < 10; ++e) {
                        if (a != 4 && b != 4 && c != 4 && d != 4 && e != 4) {
                            sum += 1;
                        }
                    }
                }
            }
        }
    }
    printf("%d", sum);
}

2.星系炸弹

题目描述

在X星系的广袤空间中漂浮着许多X星人造“ 炸弹",用来作为宇宙中的路标.
每个炸弹都可以设定多少天之后爆炸.
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸.
有一个贝塔炸弹,2014年 11月9日放置,定时为1000天,请你计算它爆炸的准确日
期.
请填写该日期,格式为yyyy-mm-dd 即4位年份2位月份2位日期.比如: 2015-02-19
请严格按照格式书写.不能出现其它文字或符号.

记得判断一下闰年,简单计算即可

#include <stdio.h>

main() {
    int year, month, day;
    printf("设定炸弹日期:");
    scanf("%d %d %d", &year, &month, &day);
    int d;
    printf("多少天后爆炸:");
    scanf("%d", &d);
    while (d > 0) {
        day += 1;
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10) {
            if (day == 32) {
                month += 1;
                day = 1;
            }
        }
        if (month == 4 || month == 6 || month == 9 || month == 11) {
            if (day == 31) {
                month += 1;
                day = 1;
            }
        }
        if (month == 2) {
            if (year % 4 == 0 && year % 100 != 0) {
                if (day == 30) {
                    month += 1;
                    day = 1;
                }
            } else if (year % 400 == 0) {
                if (day == 30) {
                    month += 1;
                    day = 1;
                }
            } else {
                if (day == 29) {
                    month += 1;
                    day = 1;
                }
            }
        }
        if (month == 12 && day == 32) {
            year += 1;
            month = 1;
            day = 1;
        }
        d--;
    }
    printf("%d-", year);
    if (month % 10 != 0) {
        printf("%d-", month);
    }
    if (day % 10 != 0) {
        printf("%d", day);
    }
    if (month % 10 == 0) {
        printf("%0d-", month);
    }
    if (day % 10 == 0) {
        printf("%0d", day);
    }
    //printf("%4d-%2d-%2d", year, month, day);
}

3.三羊献瑞

题目描述

在这里插入图片描述
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字.
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容.

观察图片共有8个不同的汉字,设三:a,羊:b,生:c,瑞:d,气:e,献:f,祥:g,辉:h,暴力循环遍历,其中三和祥从1开始

#include <stdio.h>

main() {
    for (int a = 1; a < 10; ++a) {
        for (int b = 0; b < 10; ++b) {
            if (b != a) {
                for (int c = 0; c < 10; ++c) {
                    if (c != a && c != b) {
                        for (int d = 0; d < 10; ++d) {
                            if (d != a && d != b && d != c) {
                                for (int e = 0; e < 10; ++e) {
                                    if (e != a && e != b && e != c && e != d) {
                                        for (int f = 0; f < 10; ++f) {
                                            if (f != a && f != b && f != c && f != d && f != e) {
                                                for (int g = 1; g < 10; ++g) {
                                                    if (g != a && g != b && g != c && g != d && g != e && g != f) {
                                                        for (int h = 0; h < 10; ++h) {
                                                            if (h != a && h != b && h != c && h != d && h != e &&
                                                                h != f && h != g) {
                                                                if (g * 1000 + d * 100 + c * 10 + h + a * 1000 +
                                                                    b * 100 + f * 10 + d ==
                                                                    a * 10000 + b * 1000 + c * 100 + d * 10 + e) {
                                                                    printf("%d %d %d %d\n", a, b, f, d);
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

4.格子中输出

题目描述
StringInGrid函数会在一一个指定大小的格子中打印指定的字符串.
要求字符串在水平、垂直两个方向上都居中.
如果字符串太长,就截断.
如果不能恰好居中,可以稍稍偏左或者偏上-一点.
下面的程序实现这个逻辑,请填写划线部分缺少的代码.

要求输出:
在这里插入图片描述

#include <stdio.h>

#include <string.h>


void StringInGrid(int width, int height, const char *s) {

    int i, k;

    char buf[1000];

    strcpy(buf, s);

    if (strlen(s) > width - 2) buf[width - 2] = 0;


    printf("+");

    for (i = 0; i < width - 2; i++) printf("-");

    printf("+\n");


    for (k = 1; k < (height - 1) / 2; k++) {

        printf("|");

        for (i = 0; i < width - 2; i++) printf(" ");

        printf("|\n");

    }


    printf("|");


    printf("%*s%s%*s", (width-strlen(s)-2)/2,"",s,(width-strlen(s)-2)/2,"");  //填空



    printf("|\n");


    for (k = (height - 1) / 2 + 1; k < height - 1; k++) {

        printf("|");

        for (i = 0; i < width - 2; i++) printf(" ");

        printf("|\n");

    }


    printf("+");

    for (i = 0; i < width - 2; i++) printf("-");

    printf("+\n");

}


int main() {

    StringInGrid(20, 6, "abcd1234");

    return 0;

}

在scanf里用*修饰符,是起到过滤读入的作用,例如printf("%*s",2,"")代表的是输出2个空格
由于需要将字符串居中,所以我们需要将输入的字符串前面预留空格,后面也要留出空格,经过计算我们不难发现在前面需要width-strlen(s)-2)/2个空格,后面也是width-strlen(s)-2)/2个空格

5.九数组分数

题目描述
1,2.3…9这九个数字组成-一个分数,其值恰好为1/3,如何组法?
下面的程序实现了该功能,请填写划线部分缺失的代码.

此题使用了回溯算法,个人认为偏难,此题让递归将其全排列,最终在test()函数中进行验证,全排列需要在其排列之后再将原数组列出来,否则会打乱顺序

#include <stdio.h>

void test(int x[]) {
    int a = x[0] * 1000 + x[1] * 100 + x[2] * 10 + x[3];
    int b = x[4] * 10000 + x[5] * 1000 + x[6] * 100 + x[7] * 10 + x[8];
    if (a * 3 == b) printf("%d/%d\n", a, b);
}

void f(int x[], int k) {
    int i, t;
    if (k >= 9) {
        test(x);
        return;
    }
    for (i = k; i < 9; ++i) {
        {
            t = x[k];
            x[k] = x[i];
            x[i] = t;
        }
        f(x, k + 1);
        {t = x[k], x[k] = x[i], x[i] = t;}//填空
    }
}

int main() {
    int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    f(x, 0);
    return 0;
}

6.加法变乘法

题目描述

我们都知道: 1+2+3+… +49= 1225,现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如: 1+3+…+1011+12.+…+2728+29+…+49= 2015就是符合要求的答案.
请你寻找另外-一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10).
注意:需要你提交的是一一个整数,不要填写任何多余的内容.

刚开始我对此题没有什么想法,看了很多大佬的思路才发现一种较为简单的思路
满足题目要求,设x,y分别为两个不相邻的数字,且(x+1)与y也不相邻
则我们可以知道
在这里插入图片描述
在这里插入图片描述
通过解方程,我们可以得到如下式子:
在这里插入图片描述
简化得:
在这里插入图片描述
设两个变量进行循环,两个变量表示待确定的数
我们由题目可分析出
在这里插入图片描述
在这里插入图片描述

代码如下:

#include <stdio.h>

main() {
    int x, y;
    for (int i = 1; i <= 45; ++i) {
        x = i;
        for (int j = i + 2; j <= 48; ++j) {
            y = j;
            if (x * x + y * y - x - y == 792) {
                printf("%d\n", x);
            }
        }
    }
}

我们可以得知其中一个数字为10,一个为16

7.牌型种数

题目描述
小明被劫持到X赌城,被迫与其他3人玩牌.
一副扑克牌(去掉大小王牌,共52 张),均匀发给4个人,每个人13张.
这时,小明脑子里突然冒出一一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的
初始牌型组合一共有 多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字.

a,b,c,d,e,f,g,h,i,j,k,l,m分别表示13种牌型,每个牌型有四张,只要加起来和为13就代表一个人的牌,完成一次判断总数加一

#include <stdio.h>

main() {
    int sum = 0;
    for (int a = 0; a <= 4; ++a) {
        for (int b = 0; b <= 4; ++b) {
            for (int c = 0; c <= 4; ++c) {
                for (int d = 0; d <= 4; ++d) {
                    for (int e = 0; e <= 4; ++e) {
                        for (int f = 0; f <= 4; ++f) {
                            for (int g = 0; g <= 4; ++g) {
                                for (int h = 0; h <= 4; ++h) {
                                    for (int i = 0; i <= 4; ++i) {
                                        for (int j = 0; j <= 4; ++j) {
                                            for (int k = 0; k <= 4; ++k) {
                                                for (int l = 0; l <= 4; ++l) {
                                                    for (int m = 0; m <= 4; ++m) {
                                                        if (a + b + c + d + e + f + g + h + i + j + k + l + m == 13) {
                                                            sum++;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    printf("%d",sum);
}

8.移动距离

题目描述
X星球居民小区的楼房全是-样的,并且按矩阵样式排列.其楼房的编号为1,2,3…
当排满一行时,从下一行相邻的楼往反方向排号.
比如:当小区排号宽度为6时,开始情形如下:
123456
121110987
13 14 15…
我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线
可移动)
输人为3个整数w m n,空格分开,都在1到10000范围内
w为排号宽度,m,n 为待计算的楼号.
要求输出-一个整数,表示m n两楼间最短移动距离.
例如:
用户输入:
6 8 2
则,程序应该输出: .
再例如:
用户输人:
4 7 20
则,程序应该输出:
资源约定:
峰值内存消耗< 256M
CPU消耗< 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“ 请您输人…”的多 余内容.
所有代码放在同-一个源文件中,调试通过后, 拷贝提交该源码.
注意: main函数需要返回0
注意:只使用ANSI C/ANSIC++标准,不要调用依赖于编译环境或操作系统的特殊函
数.
注意:所有依赖的函数必须明确地在源文件中#include ,不能通过工程设置而
省略常用头文件.
提交时,注意选择所期望的编译器类型。

本题可以直接通过两个楼之间的坐标进行计算,我们通过楼号可以知道该楼在数组中的位置下标,需要对正号和逆号进行区分,在两个楼同号时可以直接横坐标相减,在两个楼一正一逆时,需要将它们的正逆统一,这里采用的是将正号坐标转为逆号坐标

#include<iostream>

int main() {
    int w, m, n;
    scanf("%d %d %d", &w, &m, &n);
    m--;
    n--;
    int x1 = m / w;
    int x2 = n / w;
    int y1 = m % w;
    int y2 = n % w;
    if (x1 % 2 == 0) y1 = w - y1 - 1;
    if (x2 % 2 == 0) y2 = w - y2 - 1;
    printf("%d", abs(x1 - x2) + abs(y1 - y2));
    return 0;
}

9.垒骰子

题目描述
赌圣atm晚年迷恋上了垒骰子,就是把骰子-一个垒在另一个,上边,不能歪歪扭扭,要垒
成方柱体.
经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!
我们先来规范一下骰子: 1的对面是4, 2的对面是5, 3的对面是6.
假设有m组互斥现象,每组中的那两个数字的面紧贴在-起,骰子就不能稳定的垒起
来.
atm想计算- -下有多少种不同的可能的垒骰子方式.
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相
同.
由于方案数可能过多,请输出模10^9+ 7的结果.
不要小看了atm 的骰子数量哦~
[输人格式]
第一行两个整数n,m
n表示骰子数目
接下来m行,每行两个整数ab,表示a和b数字不能紧贴在一起.
「输出格式]
一行一个数,表示答案模10^9+7 的结果.
「样例输入]
12
「样例输出]
544
「数据范围]
对于30%的数据: n<=5
对于60%的数据: n<= 100
对于100%的数据: 0<n<= 10^9, m<= 36
资源约定:
峰值内存消耗< 256M
CPU消耗< 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输…”的多 余内容.
所有代码放在同一一个源文件中,调试通过后,拷贝提交该源码.
注意: main函数需要返回0
注意:只使用ANSICANSIC++标准,不要调用依赖于编译环境或操作系统的特殊函
数.
注意:所有依赖的函数必须明确地在源文件中#tinclude,不能通过工程设置而
省略常用头文件.
提交时,注意选择所期望的编译器类型.

10.生命之树

9、10暂时不会,后面学到了解法再写,先写这么多

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值