题目大意:给出一个密码锁,两个人一起玩游戏,给出初始的密码,规定:

  1. 每一次都可以转动一个位置的数字一个单位
  2. 不可以转动到已经出现过的数字
  3. 不可以转动到被 ban 掉的数字

无法转动的人视为失败,问谁能获胜

题目分析:二分图博弈的模板题,定义参考:https://blog.csdn.net/qq_36797743/article/details/80043107

对于此题而言,每次将数字的某个位置转动一个单位,其数位和的奇偶性会发生变化,从这里入手,将所有数字拆分成一张二分图

建图如下:

  1. 源点 -> 奇数:流量为 1
  2. 奇数 -> 偶数:如果数位和的绝对值相差 1 个单位:流量为 1
  3. 偶数 -> 汇点:流量为 1

先不建起点跑最大流,然后把起点加上,看看有没有增广路即可

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e6+100;int fac[6]={1,10,100,1000,10000,100000};bool ban[N],odd[N];struct Edge
{int to,w,next;
}edge[N];//边数int head[N],cnt;void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{memset(ban,false,sizeof(ban));memset(now,0,sizeof(now));memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);for(int i=0;i<=100000;i++){int t=i,temp=0;while(t){temp+=t%10;t/=10;}odd[i]=temp&1;}int w;cin>>w;while(w--){init();int st=N-1,ed=st-1;int n,m,start;scanf("%d%d%d",&n,&m,&start);while(m--){int num;scanf("%d",&num);ban[num]=true;}for(int i=0;i<fac[n];i++){if(ban[i])continue;if(odd[i])//odds{if(i!=start)addedge(st,i,1);string s=to_string(i);while(s.size()<n)s="0"+s;for(int j=0;j<n;j++){string ss=s;ss[j]=(ss[j]-'0'+1)%10+'0';addedge(i,stoi(ss),1);ss[j]=(ss[j]-'0'-2+10)%10+'0';addedge(i,stoi(ss),1);}}else if(i!=start)addedge(i,ed,1);}solve(st,ed);if(odd[start])addedge(st,start,1);elseaddedge(start,ed,1);if(solve(st,ed))puts("Alice");elseputs("Bob");}return 0;
}

2020CCPC(长春) - Combination Lock(二分图博弈)相关推荐

  1. 2020CCPC长春

    2020CCPC长春 题号 题目 难度 知识点 A Krypton 签到 01背包 B The Tortoise and the Hare C Quantum Geometry D Meaningle ...

  2. BZOJ 1443 二分图博弈 网络流

    思路: 二分图博弈嘛 找到最大匹配的必须点 跑个网络流 前后DFS一遍 //By SiriusRen #include <queue> #include <cstdio> #i ...

  3. [NOI2011]兔兔与蛋蛋游戏 二分图博弈

    题面 题面 题解 通过观察,我们可以发现如下性质: 可以看做是2个人在不断移动空格,只是2个人能移动的边不同 一个位置不会被重复经过 : 根据题目要求,因为是按黑白轮流走,所以不可能重复经过一个点,不 ...

  4. 【LOJ6033】棋盘游戏【二分图博弈】

    传送门 显然是个二分图,设开始位置是左边,另一边是右边 那么先手是把左边挪到右边,后手是把右边挪到左边,不能挪的那方失败 结论:Alice必胜当且仅当开始位置不一定在最大匹配上 必要性: 如果开始位置 ...

  5. usaco Combination Lock

    w我不知道咋回事思路不清晰这题前面不知道在写什么.没什么好说的枚举就行了. /* ID: jinbo wu LANG: C++ TASK: combo */ #include<bits/stdc ...

  6. USACO Section1.3 Combination Lock 解题报告

    combo解题报告 -- icedream61 博客园(转载请注明出处) --------------------------------------------------------------- ...

  7. 号码锁 Combination Lock

    题目描述 农夫约翰的奶牛不停地从他的农场中逃出来,导致了很多损害.为了防止它们再逃出来,他买了一只很大的号码锁以防止奶牛们打开牧场的门. 农夫约翰知道他的奶牛很聪明,所以他希望确保它们不会在简单地试了 ...

  8. [USACO1.3]号码锁 Combination Lock

    https://www.luogu.org/recordnew/show/17460324 题解: /* *@Author: STZG *@Language: C++ */ #include < ...

  9. 2020CCPC(长春) - Ragdoll(启发式合并+带权并查集)

    题目大意:初始时给出 n 个集合,每个集合中都包含有一个数字,现在要求执行 m 次操作,每次操作分为下列三种类型: 1 x y:在 x 位置新建一个集合,并且放置一个数字 y 2 x y:合并集合 x ...

最新文章

  1. Vitis-AI集成
  2. 【计算理论】计算复杂性 ( 无向图独立集问题 | 独立集问题是 NP 完全问题证明思路 | 证明独立集问题是 NP 完全问题 )
  3. 跨链Cosmos(10) IBC接口
  4. 参数等效模型可以用于_盘式永磁涡流驱动器的电磁温度耦合解析模型
  5. 2000年考研英语阅读理解文章三
  6. 【BZOJ2120】数颜色,带修莫队
  7. C#多线程之线程池篇2
  8. php 防止access token过期,微信調用接口,防止Access_token過期的方法
  9. Xcode8自带注释不管用解决办法
  10. mysql索引平衡树hash_MySQL B+树索引和哈希索引的区别
  11. 单片机交通灯灯c语言程序,关于LED模拟交通灯单片机C语言程序设计
  12. 教你如何制作浪漫的表白网站 七夕情人节表白网页在线制作(多种款式)
  13. Labview2019安装
  14. 极目智能完成2亿元C1轮融资,已获多个乘用车ADAS项目定点
  15. Spring定时器@Scheduled
  16. linux查看网络静态ip配置文件,linux 配置静态ip地址
  17. 2022 年最新博客专家申请流程
  18. 1068 万绿丛中一点红
  19. STM32F7以太网HAL库源文件(stm32f7xx_hal_eth.c)笔记
  20. 数据库原理第二章测验(标黑的为答案)

热门文章

  1. java tcp发消息给硬件_java – TCP客户端/服务器通信只发送第一条消息?
  2. 往IOC 容器中添加组件的方式
  3. Spring Cloud Stream的使用(上)
  4. java imap 标记已读,JavaMail通过IMAP和POP3接收未读以及设置已读邮件
  5. 方法重载(overload)和方法重写(override)的比较
  6. head first servlet jsp 学习笔记
  7. hasOwnProperty
  8. 自动化测试和手工测试
  9. open-falcon的邮件报警
  10. redis从入门到实践