【蓝桥杯31日冲刺】冲刺第18日(C++)

🌐前言🌐

  • 😃大家好啊,我是FyHAng。今天是蓝桥杯31日冲刺的第18天。我将给大家带来今日三题的题解。一起加油!💪


一、找素数

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
素数就是不能再进行等分的整数。比如:7,11。而 9 不是素数,因为它可以平分为 3 等份。一般认为最小的素数是2,接着是 3,5,…
请问,第 100002(十万零二)个素数是多少?
请注意:“2” 是第一素数,“3” 是第二个素数,依此类推。

#include <bits/stdc++.h>
using namespace std;

bool isPrime(int a)
{
	if(a == 2 || a == 3) return true;
	
	for(int i = 1; i * i <= a; i++)
		if(a % i == 0 && i != 1) return false;
	
	return true;
}

int main()
{
	int num = 2;
	int cnt = 0;
	while(true)
	{
		if(isPrime(num)) cnt++;
		
		if(cnt == 100002)
		{
			cout << num << endl;
			break;
		}

		num++;
	}
	
	return 0;
}


二、分考场

题目描述
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
输入格式
  第一行,一个整数n(1<n<100),表示参加考试的人数。
  第二行,一个整数m,表示接下来有m行数据
  以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
输出格式
  一行一个整数,表示最少分几个考场。

#include <bits/stdc++.h>
using namespace std;

const int N = 110;

int n, m;
int min_room;
int g[N][N];	//g[1][0]=2 表示 1考场的第一个学生是考生 2 
int vis[N][N];	//vis[i][j] 表示 i 和 j 认识

void dfs(int x, int room)
{
	if(room >= min_room) return ;
	if(x > n)
	{
		if(room < min_room) min_room = room;
		return ;
	}
	
	for(int i = 1; i <= room; i++)
	{
		int k = 0;
		while(g[i][k] && !vis[x][g[i][k]]) k++;
		if(!g[i][k])
		{
			g[i][k] = x;
			dfs(x + 1, room);
			g[i][k] = 0;
		}
	}
	g[room + 1][0] = x;
	dfs(x + 1, room + 1);
	g[room + 1][0] = 0;
}

int main()
{
	cin >> n >> m;
	int a, b; 
	for(int i = 0; i < m; i++)
	{
		cin >> a >> b;
		vis[a][b] = vis[b][a] = 1;
	}
	
	min_room = n;
	
	dfs(1, 0);
	
	cout << min_room << endl;
	
	return 0;
} 

三、合根植物

题目详情
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
  第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
  接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
  接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。
  格子的编号一行一行,从上到下,从左到右编号。
  比如:5 * 4 的小格子,编号:
  1 2 3 4
  5 6 7 8
  9 10 11 12
  13 14 15 16
  17 18 19 20

#include <bits/stdc++.h>
using namespace std;

const int N = 1000010;

int n, m, k;
int p[N];
bool st[N];

int find(int x)
{
	if(p[x] != x) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d", &n, &m);
	
	for(int i = 1; i <= n * m; i++) p[i] = i;	

	scanf("%d", &k);
	int a, b;
	while(k--)
	{
		scanf("%d%d", &a, &b);
		if(find(a) == find(b)) continue;
		p[find(a)] = find(b);
	}
	
	int res = 0;
	for(int i = 1; i <= n * m; i++)
	{
		if(st[find(i)]) continue;
		if(find(i))
		{
			st[find(i)] = true;
			res++;
		}
	}
	
	cout << res << endl;
	
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值