题解 | Lights-牛客假日团队赛12K题

Lights

https://ac.nowcoder.com/acm/contest/1081/K

题目描述

Bessie and the cows were playing games in the barn, but the power was reset and the lights were all turned off. Help the cows get all the lights back on so they can resume their games.
The N (1 <= N <= 35) lights conveniently numbered 1..N and their switches are arranged in a complex network with M (1 <= M <= 595) clever connection between pairs of lights (see below).
Each light has a switch that, when toggled, causes that light -- and all of the lights that are connected to it -- to change their states (from on to off, or off to on).
Find the minimum number of switches that need to be toggled in order to turn all the lights back on.
It's guaranteed that there is at least one way to toggle the switches so all lights are back on.

输入描述:

* Line 1: Two space-separated integers: N and M.
* Lines 2..M+1: Each line contains two space-separated integers representing two lights that are connected. No pair will be repeated.

输出描述:

* Line 1: A single integer representing the minimum number of switches that need to be flipped in order to turn on all the lights.

示例1

输入
5 6 
1 2 
1 3 
4 2 
3 4 
2 5 
5 3 
输出
3
说明
There are 5 lights. Lights 1, 4, and 5 are each connected to both lights 2 and 3.
Toggle the switches on lights 1, 4, and 5.

解答

状压,时间空间都不行,如果每次搜索一半就可以省下很多空间,用map记下每种状态的答案,最后再把两次的答案合并

然而正解是高斯消元解异或方程组,最后搜索自由元

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define ll long long
using namespace std;
const int maxn=40;
const int maxm=600;
int n,m,p,ans=36,fl;
ll f[maxn];
map<ll,int>mx;//每种状态的最小代价 
void dfsl(int x,ll s,int k){
    if(x==m){
        int &t=mx[s];//注意传址的引用 
        if(!t)t=k;
        else if(t>k)t=k;
        return;
    }
    dfsl(x+1,s,k);
    dfsl(x+1,s^f[x],k+1);
}
void dfsr(int x,ll s,int k){
    if(x==m){
        int t=mx[s];
        if(t && t+k-1<ans)ans=t+k-1;
        return;
    }
    dfsr(x+1,s,k);
    dfsr(x+1,s^f[x+m],k+1);
}
int main(){
    scanf("%d%d",&n,&p);
    if(n&1)n++,fl=1;//处理折半搜索 
    m=n/2;
    for(int i=1,x,y;i<=p;i++){
        scanf("%d%d",&x,&y);
        x--,y--;
        f[x]|=1LL<<y,f[y]|=1LL<<x;
    }
    for(int i=0;i<n;i++)f[i]|=1LL<<i;
    dfsl(0,(1LL<<n)-1,1);
    dfsr(0,0,0);
    printf("%d",ans-fl);
}

来源:weixin_30522183 
全部评论
大佬现在还打比赛吗
点赞 回复 分享
发布于 2020-02-19 08:42

相关推荐

来个大佬救一下,为上投了都是石沉大海了,没实习经历的话怕秋招直接进不了面。什么实习这么难找,基本
心态爆炸了:现在正式的岗位都少,实习基本不咋招的,除了大厂,中小企业其实没那么多岗位需求,就算是有,大多都是招一两个廉价劳动力,同时,他们也会希望你一来就能干活的,没时间培训你,就让你了解公司的项目,你了解完就可以开始干活。再者是,很多低质量的实习其实用处没有那么大的。我去年也是找实习找到破防,最后去了一家深圳的小公司实习,工作对我来说很简单,甚至不如我在学校做的项目,秋招的时候,这段实习经历也并没有帮上什么忙,投递简历,依旧非常低的回复率。低回复率是常态,尤其是找实习,找不到,那就把重心放在优化自己的简历和项目,多看八股文,锻炼自己的面试能力,多看别人的面经,自己模拟面试,等秋招的时候,只要有那么寥寥几次,好好抓住那几次机会。
点赞 评论 收藏
分享
05-30 12:03
山西大学 C++
offer来了我跪着...:不是骗子,等到测评那一步就知道为啥这么高工资了
点赞 评论 收藏
分享
门口唉提是地铁杀:之前b站被一个游戏demo深深的吸引了。看up主页发现是个初创公司,而且还在招人,也是一天60。二面的时候要我做一个登录验证和传输文件两个微服务,做完要我推到github仓库,还要我加上jaeger和一堆运维工具做性能测试并且面试的时候投屏演示。我傻乎乎的做完以后人家跟我说一句现在暂时不招人,1分钱没拿到全是白干
你的秋招第一场笔试是哪家
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务