C语言之蓝桥杯习题(3)☞暴力求解版(思路写在解题过程中)

第一题.

1.问题:小蓝数字卡片题

小蓝有很多数字卡片,每张卡片上都是数字0到9。 小蓝准备用这些卡片来拼一些数,他想从1开始拼现在小蓝手里有0到9的卡片各2021张,共20210张,请问小蓝可以从1拼到多少?

2.解题过程:

(1).转化字符串法:

//法一
struct num { char a; int b; };
struct num x[10];//结构体数组用于存放数字和其卡片数量
int main()
{
    char m[10] = { '0' };
    int arr[10] = { 0 };
    int a, b, c, d;
    for (a = 0; a < 10; a++)//存放0`9
    {
        x[a].a = '0' + a;
    }
    for (a = 0; a < 10; a++)//存放卡牌数
    {
        x[a].b = 2021;
    }
    for (a = 1;; a++)
    {
        sprintf(m, "%d", a);//数字转化字符
        b = strlen(m);
        for (c = 0; c < b; c++)
        {
            for (d = 0; d < 10; d++)
            {
                if (x[d].b == 0)判断是否有一个数字卡牌用完,然后输出结束所有循环
                {
                    goto h;
                }
                else
                {
                    if (m[c] == x[d].a)//进行相应卡牌的减少
                    {
                        x[d].b--; break;
                    }
                }
            }
        }
    }h:printf("%d", a - 1);
    return 0;
}

(2).直接(暴力求解)法

//法二
int arr[10];
void judge(int a)//进行卡片数量的加减
{
    switch (a)
    {
    case 0:arr[0]--;
        break;
    case 1:arr[1]--;
        break;
    case 2:arr[2]--;
        break;
    case 3:arr[3]--;
        break;
    case 4:arr[4]--;
        break;
    case 5:arr[5]--;
        break;
    case 6:arr[6]--;
        break;
    case 7:arr[7]--;
        break;
    case 8:arr[8]--;
        break;
    case 9:arr[9]--;
        break;
    }
}
void part(int a)//计算其个位的数据是几
{
    if (a < 10)
        judge(a % 10);//返回judge函数进行相应的卡片加减
    else
    {
        judge(a % 10);//将较大的数据利用递归返回其每一位的数据进入judge,进行相应的卡片加减
        a = a / 10;
        part(a);
    }
}
int main()
{int a = 0;
    for (a = 0;a<10; a++)//0~9个元素都存入2021使用一张减1;
    {
        arr[a] = 2021;
    }
    for (a = 0;; a++)
    {
        part(a);//主判断过程
        for (int b = 0; b < 10; b++)
        {
            if (arr[b] == 0)//判断是否有一个数字卡牌用完,然后输出
            {
                printf("%d", a);
                goto h;//结束所有循环
            }
        }
    }h:
    return 0;}

3.结果:

4.方法总结:

(1).法一关键点:利用结构体数组与sprintf函数

(2).法二关键点:利用递归,%的妙用

第二题.

1.问题:利用坐标确定直线。(暴力求解)

    • 解题过程

struct sb { int a; int b; };
struct sb lqb[20 * 21];//1以上是构建数据放坐标
int l = 0;//提前吧平行x,y轴直线算上
int main()
{
    int c = 0, k, b;
    for (int a = 0; a < 20; a++)//每个元素内放上不同的坐标
    {
        for (int b = 0; b < 21; b++)
        {
            lqb[c].a = a;
            lqb[c].b = b;
            c += 1;
        }
    }
    for (int a = 0; a < 420; a++)//
    {
        for (int b = 0; b < 420; b++)
        {
            if ((lqb[a].a != lqb[b].a) && (lqb[a].b != lqb[b].b))
            {
                l++;//l存放不同的直线
            }
        }
    }l = l / 2;//除以二是因为排列组合没有顺序
    printf("%d", l+20+21);
    return 0;
}
    • 结果

40257

第三题.

    • 问题:回文日期

    • 解题过程

int month2[13] = { 0,31,29,31,30,31,30,31,31,30,31,30,31 };//闰年
int month1[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//平年
int part2(int x)//判断是否为闰年
{
    if ((x % 4 == 0 && x % 100 != 0) || (x % 400 == 0))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
int judge(char *a)//此函数用于判断数据是否为合法日期
{
    int h;
    int arr[10] = { 0 };
    for (int b = 0; b < 4; b++)
    {
        arr[b] = a[b] - '0';
    }h = arr[3] * 1000 + arr[2] * 100 + arr[1] * 10 + arr[0];
    if (part2(h))//根据年份不同,合法日期也是不同的
    {
        if ((arr[0] * 10 + arr[1]) <= 12)
        {   if (month2[arr[0] * 10 + arr[1]] >= (arr[2] * 10 + arr[3]))
            {return 1;}
            else
            {return 0;}
        }
        else
        {
            return 0;
        }
    }
    else
    {
        if ((arr[0] * 10 + arr[1]) <= 12)
        {
            if (month1[arr[0] * 10 + arr[1]] >= (arr[2] * 10 + arr[3]))
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }

    }

}
int part(a)//数据反过来存放当作月日
{
    char c='0';
    char arr[10] = { '0' };
    sprintf(arr,"%d",a );
    for (int b = 0; b < 2; b++)
    {
        c = arr[b];
        arr[b] = arr[3 - b];
        arr[3 - b] = c;
    }
    if (judge(arr))//judge判断是否为合法日期
        return 1;
    else
        return 0;
}
void part1(int a)//打印该回文日期
{
    char arr[10] = { "0" };
    sprintf(arr, "%d", a);
    char c = '0';
    for (int b = 0; b < 4; b++)
    {
        arr[7 - b] = arr[b];
    }
    for (int b = 0; b < 8; b++)
    {
        printf("%c", arr[b]);
    }
}
int main()
{int y = 1;
    int a = 1212;
    scanf("%d", &a);//输入日期
    a = a / 10000;//因为每年至多有一个回文日期所以直接算年然后看倒过来是否合法
    p:
    for (int b = 1;; b++)
    {
        a += 1;
        if (part(a))//将数据反过来当作月日,再判断,为合法日期返回1,停止循环
            break;
    }
    if (y == 1)
    {
        y--;
        part1(a);//只打印一次普通回文日期;
    }
    else
        ;
    char arr[10] = { "0" };
    sprintf(arr, "%d", a);
    if ((arr[0] == arr[2]) && (arr[1] == arr[3]))//判断是否为ababbaba型回文时期并输出
    {    printf("\n");
        part1(a);
    }
    else
        goto p;//不是则返回到循环前继续循环
    return 0;
}
    • 结果

  • 32
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值