正题

题目链接:https://www.luogu.com.cn/problem/CF1427F


题目大意

有一个1∼6n1\sim 6n1∼6n的序列,两个人轮流操作,每次取走连续的三个数字。

现在给出先手取走的数字集合,要求构造方案。

保证有解

1≤n≤2001\leq n\leq 2001≤n≤200


解题思路

我们给先手取的颜色标为000,后手的颜色标为111。

我们考虑一下能不能求出哪些牌是在一次中取走的,这个取法很像一个括号匹配,也就是一次取走的东西中不会产生交叉,而如果不会产生交叉,那么我们按照括号匹配的找法去找也是对的。

所以我们可以用一个栈存按顺序存牌,当栈顶三个颜色相同时就弹出这三个,表示这三个是在同一次中取走的。

并且我们还能建立一些依赖关系,形如取走xxx之前必须yyy,这些依赖关系能构成一个森林。

现在相当于给出这样一棵森林,每次取走一个叶子,要求颜色是010101交错的。

我们找一下这个森林的性质,会发现每个节点的颜色都和父节点的不同,还有000和111的数量相等。

一种取法是000和111都随便取,但是111必须留下一个根到最后取,现在我们证明这种取法的正确性:

首先如果用这种取法正确,那么一个有解的状态就是存在一个为111的根并且存在一个当前要取的颜色的叶子。然后我们证明所有有解状态都能转移到有解状态即可。

  • 假设现在要取000,那么此时010101数量相同。假设随便一个000后就没有了111的叶子,此时111的数量比000多111,并且有一个为111的根,因为没有为111的叶子,应该每个111都能找到一个为000的儿子,但是111的数量比000多,所以显然不合法,假设不成立。

  • 假设现在要取111,那么此时取走随便一个不是最后一个根的111后010101数量相同,假设此时没有为000的儿子。我们每个000去找儿子中的一个111,理论上也应该找得到,但是因为有一个111是根,所以至少有一个000找不到这样一个儿子,所以假设不成立。

所以我们的取法就是除了最后一个为111的根以外其他的都随便取。

时间复杂度:O(n)O(n)O(n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int N=1500;
int n,cnt,wrt,v[N],_v[N],T[N],p[N],s[N],nrt[N];
vector<int> ans,G[N],prt[N];
deque<int> q[2];
void dfs(int x){if(!G[x].size())q[_v[x]].push_back(x);for(int i=0;i<G[x].size();i++){int y=G[x][i];dfs(y);T[y]=x;}return;
}
void rel(int x){ans.push_back(x);if(!T[x])return;G[T[x]].pop_back();if(G[T[x]].empty())q[_v[T[x]]].push_front(T[x]);return;
}
int main()
{scanf("%d",&n);n=n*6;for(int i=1;i<=n;i++)v[i]=1;for(int i=1,x;i<=n/2;i++)scanf("%d",&x),v[x]=0;int top=0;stack<int> z;for(int i=1;i<=n;i++){s[++top]=i;if(top>2&&v[s[top]]==v[s[top-1]]&&v[s[top]]==v[s[top-2]]){++cnt;p[s[top-2]]=cnt;_v[cnt]=v[s[top]];prt[cnt].push_back(s[top-2]);prt[cnt].push_back(s[top-1]);prt[cnt].push_back(s[top]);while(!z.empty()&&z.top()>s[top-2])G[cnt].push_back(p[z.top()]),nrt[p[z.top()]]=1,z.pop();z.push(s[top-2]);top-=3;}}int c=0;for(int i=1;i<=cnt;i++)if(!nrt[i])dfs(i),c+=_v[i];for(int i=1;i<=n/6;i++){rel(q[0].front());q[0].pop_front();if(i==n/6){if(wrt)ans.push_back(wrt);else rel(q[1].front());}else{int x=q[1].front();c-=(_v[x]==1&&!nrt[x]);if(!nrt[x]&&_v[x]==1&&!c){wrt=x;q[1].pop_front();}rel(q[1].front());q[1].pop_front();}}for(int i=0;i<ans.size();i++,putchar('\n'))for(int j=0;j<3;j++)printf("%d ",prt[ans[i]][j]);return 0;
}

CF1427F-Boring Card Game【贪心】相关推荐

  1. 【CodeForces】893 - D Credit Card (贪心)

    题目链接 题目读了好久.. 题意: 有一个人新办了一张信用卡,初始账户上没有钱.给出两个数字q,d. q是操作次数. 操作分为三种: 当aiaia_i为正值时表示信用卡增加了aiaia_i元. 当ai ...

  2. CodeForces 893D Credit Card (贪心)

    题目链接:http://codeforces.com/problemset/problem/893/D 题意:有一张银行卡,初始账户余额为0,一个人白天可以去银行对银行卡进行存钱,第i天的晚上银行会对 ...

  3. Codeforces Round 263(Div. 2)

    layout: post title: Codeforces Round 263(Div. 2) author: "luowentaoaa" catalog: true tags: ...

  4. Codeforces 题目合集+分类+代码 【Updating...】【361 in total】

    961A - Tetris                                                模拟                                      ...

  5. 【dp 贪心】bzoj4391: [Usaco2015 dec]High Card Low Card

    巧妙的贪心 Description Bessie the cow is a huge fan of card games, which is quite surprising, given her l ...

  6. cf#401(Div. 2)B. Game of Credit Card(田忌赛马类贪心)

    题干: After the fourth season Sherlock and Moriary have realized the whole foolishness of the battle b ...

  7. Codeforces 893 D Credit Card 贪心 思维

    题目链接: http://codeforces.com/contest/893/problem/D 题目描述: 每天晚上一个数值a,如果a>0表示今天收入a元,<0表示亏损a元,=0表示去 ...

  8. bzoj4396[Usaco2015 dec]High Card Wins*

    bzoj4396[Usaco2015 dec]High Card Wins 题意: 一共有2n张牌,Alice有n张,Bob有n张,每一局点数大的赢.知道Bob的出牌顺序,求Alice最多能赢几局.n ...

  9. hdu1528 Card Game Cheater

    问题描述 Adam and Eve play a card game using a regular deck of 52 cards. The rules are simple. The playe ...

  10. upc 组队赛18 STRENGTH【贪心模拟】

    STRENGTH 题目链接 题目描述 Strength gives you the confidence within yourself to overcome any fears, challeng ...

最新文章

  1. POJ 3376 Finding Palindromes(扩展kmp+trie)
  2. 密度聚类(Density peaks Clustering)Python实现
  3. cloud foundry部署报错TypeError: can't convert Hash into String
  4. 计算机键盘音乐好汉歌,好汉歌 MIDI File Download :: MidiShow
  5. 耦合式是什么意思_定向耦合器是如何工作的?能怎样应用?看完就全明白了
  6. linux上oracle导入mysql_linux下的oracle数据库和表空间的导入导出
  7. proteus三输入与非门名字_dnf冒险团名字怎么改?冒险团名称修改方法
  8. SQL Server 数据库增删改查语句
  9. typecho图片插件_Typecho弹窗相册插件HighSlide1.4.7更新
  10. jsp+ssm+mysql实现图书馆预约占座管理系统 代码+数据库脚本+论文+答辩稿+开题报告+任务书
  11. visio画箭头时,如何去掉箭头的自动连接连接点(吸附)功能?
  12. 【深度学习】实验5答案:滴滴出行-交通场景目标检测
  13. 屏蔽CSDN右下角广告
  14. Python爬音乐--qq
  15. 2013 年开源中国 10 大热门 Java 开源项目
  16. C#实战之CAD二次开发004:插入尺寸标注
  17. Linux-X86和Linux-ARM编译binutils
  18. 光纤通信系统主要由哪几部分组成
  19. 计算机打游戏的硬件,电脑玩游戏主要看显卡吗?小白装机硬件选择误区 (全文)...
  20. Direct9到Direct10 --- 玩的就是3D图形

热门文章

  1. JavaWeb网上书城项目
  2. 如何在 iPhone 和 iPad 上将你的照片转换为 PDF?
  3. java applet.newaudioclip_Java Applet
  4. 读了7年通信最后还是转了码,这值得吗?
  5. pipe()函数详解
  6. C语言知识点--define的替换列表为空是怎么回事?
  7. 面试问题 你如何评价你上一家公司,你觉的上一家公司怎么评价你
  8. 华为手机linux终端,华为云IoT如何让“哑”终端进化为智能终端?看完这场直播你就明白了...
  9. SaaS第一,股价暴涨,25年的金蝶迎来第二春
  10. excel概率密度函数公式_使用Excel绘制F分布概率密度函数图表