分考场(蓝桥杯)

文章目录

分考场

题目描述

n 个人参加某项特殊考试。

为了公平,要求任何两个认识的人不能分在同一个考场。

求最少需要分几个考场才能满足条件。

输入描述

输入格式:

第一行,一个整数 n (1≤n≤100),表示参加考试的人数。

第二行,一个整数 m,表示接下来有 m 行数据。

以下 m 行每行的格式为:两个整数 ,a,b,用空格分开 ( 1≤a,b≤n )表示第 a 个人与第 b 个人认识。

输出描述

输出一行一个整数,表示最少分几个考场。

输入输出样例

示例

输入

5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5

输出

4  

dfs

解题思路

  1. 决策类型的搜索,使用dfs进行决策搜索
  2. 两个人之间的认识关系可以使用邻接矩阵进行存储,如果认识加一条无向边即可
  3. dfs枚举的是每个人,check现存的每一个考场,此人依次尝试进可加入的考场,尝试新开一个考场加入,也可考虑剪枝优化

代码

这段代码是用来解决考场分配问题的。具体而言,它需要确保认识的人不能分配到同一个考场。程序通过深度优先搜索(DFS)算法来寻找满足条件的最小考场数。以下是对代码的详细注释:

cpp 复制代码
#include<iostream>
#include<vector> 
using namespace std;
const int N = 110;

bool g[N][N]; // 使用邻接矩阵来表示人与人之间的认识关系,如果g[i][j]为true,则代表第i个人与第j个人认识。

vector<int> q[N]; // 使用一个向量数组q来存储每个考场中已分配的人员名单。

int ans = 100; // 初始化答案为100,这是一个上限值,因为最多有100个人,所以最多需要100个考场。

int n, m; // n代表人数,m代表已知的认识关系对数量。

// 检查某个人是否能够被分配到某个考场。
bool check(int b, int i) {
    for (int j = 0; j < q[i].size(); j++) // 遍历当前考场中的所有人。
        if (g[b][q[i][j]]) // 如果b与考场中的某个人认识,则返回false。
            return false;
    return true; // 如果b与考场中任何人都不认识,则可以分配到这个考场,返回true。
}

// DFS函数,于搜索所有可能的分配方案。
void dfs(int now, int cnt) {
    if (cnt >= ans) // 如果当前方案使用的考场数已经不小于当前找到的最小值,则停止搜索这条路径。
        return;
    
    if (now == n + 1) { // 如果所有人都已经被分配考场,更新最小考场数。
        ans = min(ans, cnt);
        return;
    }

    for (int p = 1; p <= cnt; p++) { // 尝试将当前人分配到现有的每个考场。
        if (check(now, p)) { // 如果可以分配到当前考场。
            q[p].push_back(now); // 将当前人加入到考场p中。
            dfs(now + 1, cnt); // 继续搜索下一个人的分配方案。
            q[p].pop_back(); // 回溯,将当前人从考场p中移除。
        }
    }

    // 尝试开设新的考场,并将当前人分配进去。
    if (cnt + 1 <= n) {
        q[cnt + 1].push_back(now); // 在新考场加入当前人。
        dfs(now + 1, cnt + 1); // 继续搜索下一个人的分配方案,并增加考场数。
        q[cnt + 1].pop_back(); // 回溯,将当前人从新考场中移除。
    }
}

int main() {
    cin >> n >> m; // 输入总人数和认识关系对数量。
    int a, b;
    for (int i = 0; i < m; i++) {
        cin >> a >> b; // 输入认识关系对。
        g[a][b] = g[b][a] = 1; // 在邻接矩阵中标记双向认识关系。
    }
    dfs(1, 1); // 从第1个人开始深度优先搜索,并尝试将其放入第一个考场。
    cout << ans << endl; // 输出最少需要的考场数。
    return 0;
}

代码首先读入参加考试的人数n和认识关系对数,然后读入每对认识关系并在邻接矩阵g中标记。主要逻辑在dfs函数中,它尝试所有可能的人员分配方案来寻找使用最少考场数的方案。搜索过程中,如果发现当前方案使用的考场数已经达到或超过了之前找到的最小值,则停止继续搜索该路径。当所有人都被成功分配到考场后,会更新最少需要的考场数。最终,程序输出找到的最小值作为答案。

相关推荐
Ylucius1 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
是店小二呀1 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
杰九1 小时前
【算法题】46. 全排列-力扣(LeetCode)
算法·leetcode·深度优先·剪枝
ephemerals__1 小时前
【c++】动态内存管理
开发语言·c++
CVer儿1 小时前
条件编译代码记录
开发语言·c++
程序猿练习生2 小时前
C++速通LeetCode简单第18题-杨辉三角(全网唯一递归法)
c++·算法·leetcode
汉字萌萌哒2 小时前
【2022 CCF 非专业级别软件能力认证第一轮(CSP-J1)入门级 C++语言试题及解析】
数据结构·c++·算法
th新港2 小时前
CCF201909_1
数据结构·c++·算法·ccf
意如流水任东西2 小时前
[C++]类和对象(上)
开发语言·c++
孤寂大仙v2 小时前
【C++】STL----stack和queue常见用法
开发语言·c++