蓝桥杯练习-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 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。
现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。
输入格式
第一行输两个整数 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;
}