codeforces B. Online Meeting 解题报告
题目链接:http://codeforces.com/problemset/problem/420/B
题目意思:给出一段连续的消息记录:记录着哪些人上线或者下线。问通过给出的序列,找出可能为leader的人的编号。符合leader的条件是:至少有一个人上线的时候,绝对要有该人(leader)的存在。
整个五一都把时间耗在这题里了......首先太感谢jhf大神,竟然可以这么有耐心的跟我这个陌生人讨论题目。但是,限于本人理解能力有点问题,在参考他写的代码里,还是有一些部分不太理解。
以下结合我的理解来说。首先,将有可能为leader的人分成两批:没有在序列中出现过的 + 在序列中有可能是leader的候选人。要知道记录里没有出现过的人都有可能是leader。然后,对于候选人又分成两批:整个记录中的第一人 + 记录中的某一个人。对于记录中第一个人为leader的情况有两种: (1)整个记录里只有上线的人,没有下线的; (2)整个记录里每个人第一次出现都是以上线形式出现,但记录中存在下线。这个时候最有可能为leader 的 非第一个人莫属了。对于有可能是记录中的某一个人(有可能不是第一个),需要符合:这些候选人第一次出现以 下线形式出现。
那总体的思路就是:挑出候选人,然后在候选人当中选出最后下线的,就是说,上线的人要在该人离开前都要下线。然后加上未出现过的人,就是答案了。
补充: 终于找到他的原话 + 我的补充了:
jhf:
1、先预处理 ,例如+1 -2 补充完整为: +2+1-2-1 这两个是等价的(因为所有的人都是先上线再下线)。实质上就是把直接下线而没有先上线的人的上线记录加在前面,例如-2+3-3-4-1,2 4 1直接下线了,他们是唯一有可能当leader的,然后试图从中再筛选,筛选的方法就是看这些人有没有中途在还有人在线的时候就下线了
2、然后遍历记录每走一条,淘汰那些不符合的人...
最终版:
x第一次出现是-x的形式的列为候选
|
如果没有这种的,把记录中的第一个数列为候选
|
然后开始进一步筛选
|
筛选就看这些候选中有没有在有人在线的情况下下线的
|
如果有就排除
|
然后加上那些没在记录中出现过得人就是答案
|
...
候选人在有人在线的情况下下线了
答:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int MAX_MSG = 1e5 + ;
const int MAX_PEOPLE = 1e5 + ;
int people, msg, init_num;
int ans[MAX_PEOPLE];
bool vis[MAX_PEOPLE], wait[MAX_PEOPLE]; // vis[]: 针对整个记录中没有出现过的人;wait[]:记录第一次出现是离线的人的编号 struct node
{
int id;
bool on;
}user[MAX_MSG]; void Input()
{
char ch;
scanf("%d%d", &people, &msg);
for (int i = ; i <= msg; i++)
{
cin >> ch >> user[i].id;
user[i].on = (ch == '+'); // 代表该人第一次出现是上线的
}
} void Make_wait() // 挑出候选人
{
memset(vis, , sizeof(vis));
memset(wait, , sizeof(wait));
bool did = false;
init_num = ;
for (int i = ; i <= msg; i++)
{
if (vis[user[i].id])
continue;
if (!user[i].on)
{
did = true;
init_num++; // 统计第一次出现是下线的人的数量
wait[user[i].id] = true;
}
vis[user[i].id] = true;
}
if (!did) // 候选人只有记录中的第一个人(不考虑!vis[])
wait[user[].id] = true;
} void Work() // 判断候选人
{
int on_num = init_num; // 第一次出现是以下线方式出现的人,即候选人
for (int i = ; i <= msg; i++)
{
if (user[i].on)
{
on_num++;
if (on_num == && !wait[user[i].id]) // 这条语句令我十分不解,可能是代表候选人是记录中的第一个人
{
memset(wait, , sizeof(wait));
}
continue;
}
on_num--;
if (!wait[user[i].id]) // 非候选人直接跳过
continue;
if (on_num > ) // 离线对应该人不是leader
wait[user[i].id] = false;
}
} void Output()
{
int ans_num = ;
for (int i = ; i <= people; i++)
{
if (!vis[i] || wait[i])
ans[++ans_num] = i;
}
printf("%d\n", ans_num);
if (!ans_num)
return;
for (int i = ; ans_num && i <= ans_num; i++)
printf("%d ", ans[i]);
puts("");
} int main()
{
Input();
Make_wait();
Work();
Output();
return ;
}
codeforces B. Online Meeting 解题报告的更多相关文章
- Codeforces Round 665 赛后解题报告(暂A-D)
Codeforces Round 665 赛后解题报告 A. Distance and Axis 我们设 \(B\) 点 坐标为 \(x(x\leq n)\).由题意我们知道 \[\mid(n-x)- ...
- Codeforces Round 662 赛后解题报告(A-E2)
Codeforces Round 662 赛后解题报告 梦幻开局到1400+的悲惨故事 A. Rainbow Dash, Fluttershy and Chess Coloring 这个题很简单,我们 ...
- Codeforces Round #277.5 解题报告
又熬夜刷了cf,今天比正常多一题.比赛还没完但我知道F过不了了,一个半小时贡献给F还是没过--应该也没人Hack.写写解题报告吧= =. 解题报告例如以下: A题:选择排序直接搞,由于不要求最优交换次 ...
- codeforces B. Simple Molecules 解题报告
题目链接:http://codeforces.com/problemset/problem/344/B 题目意思:这句话是解题的关键: The number of bonds of an atom i ...
- codeforces 591A. Wizards' Duel 解题报告
题目链接:http://codeforces.com/problemset/problem/591/A 题目意思:其实看下面这幅图就知道题意了,就是Harry 和 He-Who-Must-Not-Be ...
- codeforces 582A. GCD Table 解题报告
题目链接:http://codeforces.com/problemset/problem/582/A 网上很多题解,就不说了,直接贴代码= = 官方题解: http://codeforces.com ...
- codeforces 581C. Developing Skills 解题报告
题目链接:http://codeforces.com/problemset/problem/581/C 题目意思:给出 n 个数:a1, a2, ..., an (0 ≤ ai ≤ 100).给出值 ...
- codeforces 577B. Modulo Sum 解题报告
题目链接:http://codeforces.com/problemset/problem/577/B 题目意思:就是给出 n 个数(a1, a2, ..., an) 和 m,问能不能从这 n 个数中 ...
- codeforces 540B.School Marks 解题报告
题目链接:http://codeforces.com/problemset/problem/540/B 题目意思:给出 k 个test的成绩,要凑剩下的 n-k个test的成绩,使得最终的n个test ...
随机推荐
- Mysql 实现篮球比赛赛程中两支队伍的查询
表结构如下: 查询两支队伍的比赛情况,sql语句如下: SELECT t1.team_name,g.team1_score,g.team2_score,t2.team_name,g.gametime ...
- Codeforces956D. Contact ATC
$n \leq 100000$个飞机在坐标轴上,给坐标给速度,坐标速度异号,还有一个风速在$[-w,w]$区间,$w$比最小的速度绝对值要小.由于风速不知道,所以问有多少对飞机可能在原点相遇. 思维定 ...
- 标准C程序设计七---13
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 选取第K大数的快速选择算法和注意事项
快速选择算法,是一种能在大致O(N)的时间内选取数组中第k大或者k小的算法.其基本思路与快速排序算法类似,也是分治的思想. 其实这个算法是个基础算法,但是不常用,所以今天编的时候错了POJ2388,才 ...
- Strom运行监控
https://blog.csdn.net/wenxuechaozhe/article/details/80548709
- Idea Failed to read artifact descriptor for xx:jar:unknown
网上的解决方案: 根据网上说明添加了maven命令clean compile install -Dmaven.test.skip=true,与我遇到的问题不同 有的方法猜测可以通过,但是没时间测试了 ...
- 《Java虚拟机原理图解》 1.2.2、Class文件中的常量池详解(上)
我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主版本之后,紧接着就是常量池的数据区域了,如下 ...
- HDU 1501
Zipper Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- [转]java类 对象 和构造方法
github地址:https://github.com/lily1010/java_learn/tree/master/dog java中对象和类 java中万物皆对象,比如说动物,里面有猫,狗,鱼等 ...
- [UnityUI]一些有趣的UI样例
1.环形进度条 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...