蓝桥杯练习-2.24

蓝桥杯练习-2.24

代码练习

特殊回文数

思路:一个比较好的思路就是,用while将该数的每个位上的数得出来,然后存进数组中,将第一位和最后一位进行比较,看是否相等,然后一直比较到中间,同时设一个变量从0计数,以此来判断。

代码:

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
bool judge(int x,int n)
{
    int i = 0, k = 0, sum = 0;
    int a[6];
    while(x)
    {
        a[i++] = x % 10;
        x /= 10;
    }
    for (int j = 0; j < i; j++)
    {
        sum += a[j];
        if (a[j] == a[i - j - 1])
            k++;
    }
    if ((k > i / 2 + 1) && n == sum)
        return true;
    else return false;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 10000; i <=999999; i++)
    {
        if (judge (i, n))
            cout << i << endl;
    }
    return 0;
}

视频学习

视频名称及链接:

2019年蓝桥杯训练营(C++) 10.1深搜的剪枝策略视频讲解

例题:引爆炸弹

在一个 n \times mn×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

img

现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。

输入格式

第一行输两个整数 n,mn,m,用空格隔开。

接下来 nn 行,每行输入一个长度为 mm 的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。

数据约定:

对于 60%60% 的数据:1 \le n, m \le 1001≤n,m≤100;

对于 100%100% 的数据:1 \le n, m \le 10001≤n,m≤1000;

数据量比较大,不建议用cin输入。

输出格式

输出一个整数,表示最少需要手动引爆的炸弹数。

#include <cstdio>
#include <iostream>
using namespace std;
char mat[1010][1010];
int n, m;
bool row[1010],col[1010];//俩个数组用来标记每行,每列每行是否已经考虑过引爆,拿来剪枝的
void boom(int x, int y)
{
    mat[x][y] = 0;//首先标记当前炸弹已经被引爆,然后如果当前行没有被引爆过,就循环判断该行
                  //是否有没引爆的炸弹并引爆
    if (!row[x])//如果这一行先前没有被引爆过,就逐一搜索这一行的每一列,看看是否有炸弹
    {           //如果row[x]=true,就表明先前肯定搜过这行,这也是一种剪枝表示行上没被清理过
                //(清理过一次就不用再清理了)
        row[x] = true;
        for (int i = 0; i < m; ++i)// 考虑每一列,搜索这一行
        {
            if (mat[x][i] == '1')// 如果这个是炸弹,就可以炸它了
            {
                boom(x, i);
            }
        }
    }
    if (!col[y])//对于每一列也可以这样考虑,先前没有被引爆过的话
    {
        col[y] = true;
        for (int i = 0; i < n; ++i)
        {
            if (mat[i][y] == '1')
            {
                boom(i, y);
            }
        }
    }
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
    {
        scanf("%s", mat[i]);
    }
    int cnt = 0;
    for (int i = 0; i < n; ++i)//考虑每一个格子,遍历n * m的方格,每遇到一个没引爆的炸弹,答案就加1
    {
        for (int j = 0; j < m; ++j)
        {
            if (mat[i][j] == '1')//如果这块有炸弹,但还没引爆,就可以引爆一次
            {
                ++cnt;
                boom(i, j);//并调用boom函数引爆所有关联的炸弹
            }
        }
    }
    cout << cnt << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值