蓝桥杯 历届试题 分考场(DFS+枚举)
传送门
题目描述
n个人参加某项特殊考试。
为了公平,要求任何两个认识的人不能分在同一个考场。
求是少需要分几个考场才能满足条件。
输入
第一行,一个整数n(1<n<100),表示参加考试的人数。
第二行,一个整数m,表示接下来有m行数据
以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
输出
一行一个整数,表示最少分几个考场。
样例输入1
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
样例输出1
4
样例输入2
5
10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
样例输出2
5
分析
- 做这道题的思路相对还是比较暴力的,数据不算大,直接用DFS枚举出所有可能的分考场情况加上适当剪枝,从中找出考场数最少的情况即可。
- 代码核心思路:用一个第一维表示考场号、第二维表示考生编号的二维数组存储分配已分配考场的学生,以学生编号1->n的顺序给学生分配考场。首先判断能不能在已有的把他分到已有的考场中,如果不能,就开新的考场再把该学生分进去。
- 剪枝:如果当前的考场数不小于前面找到的值就可以不必往下找了(小优化)
- 如果下面代码中的函数参数为dfs(1,1)则会有一组数据运行超时,可以知道一开始考场数为0,要直接开新的考场会运行会更加高效(被坑了很久)
代码如下
import java.util.*;
public class Main {static final int maxn=105;static int map[][]=new int[maxn][maxn];//用邻接矩阵表示同学之间有没有关系static int p[][]=new int[maxn][maxn]; //存储i号考场的学生static int rs[]=new int[maxn]; //存储i号考场的学生数目static int n,m;static int cnt=maxn;static void dfs(int x,int num) { //x表示学生编号,num表示考场数if(num>=cnt)return ; //剪枝,当考场数大于现在找到的值就可以不必往下找了if(x>n) { //所有考生都分配到考场了cnt=Math.min(cnt, num);return ;}for(int i=1;i<=num;i++) { //遍历已存在的考场int k=0;for(int j=1;j<=rs[i];j++) { //遍历i号考场里面的学生if(map[x][p[i][j]]==0)k++; //判断该学生和考场里面的学生有没有关系}if(k==rs[i]) { //满足条件p[i][++rs[i]]=x;dfs(x+1, num);--rs[i]; //回溯}}//需要开新的考场p[num+1][++rs[num+1]]=x;dfs(x+1, num+1);--rs[num+1]; //回溯}public static void main(String[] args) {Scanner cin=new Scanner(System.in);n=cin.nextInt();m=cin.nextInt();for(int i=0;i<m;i++){int x=cin.nextInt();int y=cin.nextInt();map[x][y]=map[y][x]=1;}dfs(1, 0); //dfs(1,1);会超时System.out.println(cnt);}
}
代码简化
认真思考了一下,似乎那个rs[]数组不是必要的,思路还是和上面一致,于是有了以下的简化版dfs代码。 但是似乎跑得更慢了(逃
static void dfs(int x,int num) {if(num>=min)return ;if(x>n) {min=Math.min(min, num);return ;}for(int i=1;i<=num;i++) {int k=0;while(map[x][p[i][k]]==0&&p[i][k]!=0)k++;if(p[i][k]==0) {p[i][k]=x;dfs(x+1, num);p[i][k]=0;}}p[num+1][0]=x;dfs(x+1, num+1);p[num+1][0]=0;}
蓝桥杯 历届试题 分考场(DFS+枚举)相关推荐
- 蓝桥杯 历届试题 分考场 (DFS)-----C语言—菜鸟级
问题 1874: [蓝桥杯][2017年第八届真题]分考场 时间限制: 1Sec 内存限制: 128MB 提交: 62 解决: 12 题目描述 n个人参加某项特殊考试. 为了公平,要求任何两个认识的人 ...
- 蓝桥杯 历届试题 分考场(C语言)
分考场 问题描述 n个人参加某项特殊考试. 为了公平,要求任何两个认识的人不能分在同一个考场. 求是少需要分几个考场才能满足条件. 输入格式 第一行,一个整数n(1<n<100),表示参加 ...
- 【蓝桥】 历届试题 分考场(DFS,回溯,剪枝,无向图染色问题)
历届试题 分考场 时间限制:1.0s 内存限制:256.0MB 问题描述 n个人参加某项特殊考试. 为了公平,要求任何两个认识的人不能分在同一个考场. 求是少需要分几个考场才能满足条件. 输入格式 第 ...
- 蓝桥杯c语言试题幸运数,蓝桥杯 历届试题 幸运数 dfs
时间限制:1.0s 内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成 . 首先从1开始写出自然数1,2,3,4,5,6,. ...
- java 蓝桥杯历届试题 分糖果(题解)
试题 历届试题 分糖果 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半 ...
- 蓝桥杯-历届试题 分巧克力
问题描述 儿童节那天有K位小朋友到小明家做客.小明拿出了珍藏的巧克力招待小朋友们. 小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形. 为了公平起见,小明需要从这 N 块巧克力中切出 ...
- 蓝桥杯 历届试题 分糖果(模拟)
传送门 题目描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边的孩子. 一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而 ...
- [蓝桥杯][历届试题]网络寻路-dfs,图的遍历
题目描述 X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同 ...
- 蓝桥杯历届试题----分糖果(模拟)
问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边的孩子. 一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数 ...
最新文章
- jq onclick 定义_从HTML中的onClick属性调用jQuery方法
- P1198 [JSOI2008]最大数
- ASP:HTML在线编辑器的调用方法和使用方法详解
- 如何将tensorflow-yolov3(YunYang1994).txt 坐标转换成yolo的标注(annotations)
- react前端显示图片_在react里怎么引用图片
- 【Android】Fragment的简单笔记
- git学习(6):删除github镜像
- consulAPI服务的注册源码
- [译]介绍Spark2.4的用于处理复杂数据类型的新内置函数与高阶函数
- python画散点图-Python:matplotlib绘制散点图
- C++学习之-std::make_unique 与std::unique_ptr
- 计算机毕业设计 HTML+CSS+JavaScript 云南美食网页设计 美食网页介绍代码
- macbook使用共享屏幕实现VNC远程控制
- C++语法基础--句柄类
- 微博跳转淘宝,微博发布宝贝/优惠券/淘客等链接点击后直接跳转淘宝打开
- 网易云音乐部门技术面
- 信息系统项目管理师考前建议
- mysql的column是什么意思_column意思 数据库中的column是什么意思
- 重启tomcat命令
- TC-Traffic Control in Linux