Coder-Strike 2014 - Finals (online edition, Div. 2) Online Meeting

题目核心:

the leader is the person who is present at any conversation during a chat meeting. In other words, if at some moment of time at least one person is present on the meeting, then the leader is present on the meeting.

 Given the 'user logged on'/'user logged off' messages of the meeting in the chronological order, help the director determine who can be the leader. Note that the director has the record of only a continuous part of the meeting (probably, it's not the whole meeting).

Output
In the first line print integer k (0 ≤ k ≤ n) — how many people can be leaders. In the next line, print k integers in the increasing order — the numbers of the people who can be leaders. If the data is such that no member of the team can be a leader, print a single number 0.

题解: 题目读懂听快的,但是比赛时候思路一直很混乱。题意要求找 can be leaders,是 leader 的 充要条件是:只要确定会议有人在,他必须在

             言外之意:当某个人出去时候会议室确定有人在,那么出去的这个人肯定不是leader, 如果某个人进会议室前就有人在,那么进来的这个人肯定不是leader

解释一下样例:为了方便描述:time=0 表示初始状态,time=1 表示第一次记录时的状态,time=m+1 表示 记录结束之后会议室状态

Input
5 4
+ 1
+ 2
- 2
- 1
Output
4
1 3 4 5 
//
time=0: (3,4,5) //()代表可能在会议室
time=1: 1(3,4,5)
time=2: 1.2(3,4,5) //此时可以说明2 肯定不是leaders;
time=3: 1,(3,4,5)
time=4: (3,4,5)
time=5: (3,4,5)  //显然 当会议室确定有人在是 1均在,因此1,3,4,5 均没有信息表明他们can't be leader;

  
  
Input
2 4
+ 1
- 2
+ 2
- 1
Output
0
//time=0: 2;
time=1: 1,2;
time=2:1;
time=3:1.2;
time=4:2;
time=5:2;
显然1,2 均不能是leaders , time=0 时,确定2是在会议室,可是1不在,time=2,有人在会议室,而2不在,因此ans=0;
通过样例,明显可以发现直接找谁可能是leader太复杂,那么应该从反面着手,判断谁不是leader!
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
int n,m;
struct M{
   char x;
   int id;
   void init(){
      scanf("%s %d",&x,&id);
   }
}a[100010]; 
set<int>que; //维护会议室状态
bool no[100010];
bool vis[100010]; 
int ans[100010];
int main()
{
   // freopen("in.in","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        memset(no,0,sizeof(no));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++){   
          a[i].init();
          if(a[i].x=='+'&&vis[a[i].id]==0) vis[a[i].id]=1;
          else if(a[i].x=='-'&&vis[a[i].id]==0)que.insert(a[i].id); 
        }

       int mb=-1;
       for(int i=1;i<=m;i++)
       {
          if(a[i].x=='-'){
             if(que.size()>1) no[a[i].id]=1;
             else if(que.size()==1) mb=a[i].id;  
             que.erase(a[i].id);
          }
          else if(a[i].x=='+'){
            if(que.size()!=0) no[a[i].id]=1;
            else if(mb!=-1&&a[i].id!=mb) {
                no[mb]=1,no[a[i].id]=1;  
            }
            que.insert(a[i].id);
          }
       }
       int len=0;
       for(int i=1;i<=n;i++)
        if(no[i]==0) ans[len++]=i;

       printf("%d\n",len);
       if(len!=0){
        for(int i=0;i<len-1;i++)
          printf("%d ",ans[i]);
        printf("%d\n",ans[len-1]);
       }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值