首页 > 其他分享 >每天一道蓝桥杯Day1 分考场(dfs+结论)

每天一道蓝桥杯Day1 分考场(dfs+结论)

时间:2024-03-07 22:22:36浏览次数:21  
标签:图论 int dfs Day1 蓝桥 考场 ans

题意:

这道题第一眼咋看以为是图论,但是要抽象成图论的话就会变成:

给定一个无向图,要求对点染色,使得任意相邻点之间颜色不能相同,试问最少的颜色数是多少?

发现转化成图论后好像也没有什么图论算法可以解决,这个转化不是很有效。

往往不知道怎么下手时可以试着考虑极端情况,比如考虑上界/下界,答案很小会怎么样,很大会怎么样

假设现在有n个人,最少考场数是我们要求的,最多考场数呢?

n个人n个考场肯定够用,但是n个肯定太多了。

n=3时

这种情况只需要2个   

 

这种情况需要3个

n=4时

需要3个 

 需要3个

需要4个。

有一个直观的直觉:图越密,需要的考场数越多。

最密的图是完全图,也就是说n个点的图,如果需要n个考场,那么就需要n*(n-1)/2条边,而此题m<=n

我们隐约感觉到,这个上界远远达不到n,应该会小于sqrt(n)?(不会证明2333)

数据不大,就可以考虑搜索

依次遍历每个人,判断当前她能放进哪个考场,能放则放,继续搜索;还有一种情况是给此人单独开一个考场

code:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=105;
vector<int>e[N];
int ans=INT_MAX;
int at[N];
void dfs(int step,int k){
    if(k>=ans) return;//剪枝
    //如果当前用到的考场已经大于曾经找出来的最优解,则必然不会是最优解
    if(step==n+1){
        ans=min(ans,k);
        return;
    }
    for(int i=1;i<=k;i++){
        int flag=1;
        //判断是否会冲突
        for(auto v:e[step]){
            if(at[v]==i) flag=0;
        }
        if(!flag) continue;
        at[step]=i;
        dfs(step+1,k);
    }
    //单独开一个考场的情况
    at[step]=k+1;
    dfs(step+1,k+1);
}
int main(){
    
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int a,b;cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(1,0);
    cout<<ans<<endl;
}

题外话:

1.这个问题其实有背景,是很著名的图着色问题,并且是个NP问题,没有多项式解法。

2.蓝桥杯好多搜索题,不会就暴力!

3.这道题的数据出题人应该没有造的很强。刚才写了个随机数生成数据,造了一组n=100,m=100的,ac代码跑了整整好几分钟

4.有一道类似的题(https://vjudge.net.cn/problem/%E6%B4%9B%E8%B0%B7-P5194),也是表面数据很大,分析完发现其实情况有限,可以搜索解决。

标签:图论,int,dfs,Day1,蓝桥,考场,ans
From: https://www.cnblogs.com/liyishui2003/p/18059927

相关文章

  • P8686 [蓝桥杯 2019 省 A] 修改数组
    备赛蓝桥杯和icpc的习题:一道并查集的题目>#include<iostream>>#include<vector>>#include<algorithm>>#include<math.h>>#include<string>>#include<string.h>>#include<iomanip>>#include<map>&g......
  • 每日一题 Day1
    每日一题Day1无重复字符的最长子串第一印象第一想法就是使用暴力解法,遍历出每个字符串再用条件筛选符合要求的字符串,时间复杂度为O(N^2)。滑动窗口与哈希表滑动窗口(双指针)多用于处理字符串与序列的操作,根据题目的要求,求解串中符合某种条件的序列的最长或者最短的长度。在本......
  • 2020蓝桥杯c语言省赛B组
    2020蓝桥杯省赛B组1.回文日期考点枚举+翻转完整代码#include<bits/stdc++.h>usingnamespacestd;boolrn(intt){ if((t%4==0&&t%100!=0)||t%400==0)returntrue; returnfalse;}注意:是整体翻转不是年月日变成日月年!boolf(intn,inty,intr){inth=n*10000+......
  • 代码随想录算法训练营day14 | leetcode 144. 二叉树的前序遍历、145. 二叉树的后序遍
    目录题目链接:144.二叉树的前序遍历-简单题目链接:145.二叉树的后序遍历-简单题目链接:94.二叉树的中序遍历-简单递归三要素:确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递归的返回值是什么进而确定递归......
  • 小白从零开始学习编程 day1
    1.什么是编程语言编程语言是用于计算机与人沟通的介质2.什么是编程使用编程语言编写出一系列文件3.为什么进行编程通过奴役计算机,解放劳动力4.计算机的五大组成部分1.CPU(1)控制器:用于控制硬件(2)运算器:进行逻辑运算和算数运算2.内存(1)运行速度快(2)断电即......
  • 学习 Day1 MarkDown语法练习
    学习Day1MarkDown语法练习Day1,了解了MarkDown的基本语法,为日后的学习做准备。标题语法使用'#'号来标出标题的等级,如:一级标题为('#'+空格),二级标题为('##'+空格)例如:二级标题三级标题字体语法使用特定的语法给字体增加样式加粗字体(使用'**'号)倾斜字体(使用'*'号)......
  • Day1.numpy
    numpy数组的应用1.创建引入numpy库importnumpyasnp创建对象一维arr=np.array([1,2,3])二维arr=np.array([1,2,3],[4,5,6])#相当于一个二维数组2.常用属性T数组维度的转换dtype数据类型shape数组维度大小,如三行四列astype类型转换3.获取行列数arr......
  • 第十一届蓝桥杯试题B:寻找2020
    目录题目题解:暴力题目题解:暴力需要知道文件的操作;发现2020的行列标变化li=[]#创建一个空列表用于存储读取的文本内容withopen(r'2020.txt','r')asfp:#打开名为'2020.txt'的文件,并使用文件句柄fpforlineinfp.readlines():#逐行读取文件内容......
  • 代码随想录算法训练营day13 | leetcode 239. 滑动窗口最大值、347. 前 K 个高频元素
    目录题目链接:239.滑动窗口最大值-困难题目链接:347.前K个高频元素-中等题目链接:239.滑动窗口最大值-困难题目描述:给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。......
  • 第十一届蓝桥杯:数字三角形
    目录题目暴力:最大路径和题解:动态规划题目暴力:最大路径和n=int(input())#输入数塔的行数#创建一个二维数组a来表示数塔,初始值都为0a=[[0]*(n+1)for_inrange(n+1)]#从第1行开始逐行读取输入,并计算最大路径和foriinrange(1,n+1):forjinrange(1,i......