现在的位置: 首页 > 综合 > 正文

CF – 420B – Online Meeting(思维)

2019年08月30日 ⁄ 综合 ⁄ 共 1287字 ⁄ 字号 评论关闭

题意:n 个人参加线上会议,某经理记录了中间一段时间的 m 条上下线记录(1 ≤ n, m ≤ 105)。+ 表示上线,- 表示下线。leader是指只要有人在线,他都在线的人。求所有可能的leader。

题目链接:http://codeforces.com/problemset/problem/420/B

——>>这样的一种人,他们在记录中的第一条记录是下线的,定义为xx。。

三个断言:

1)如果xx存在,那么出现的人中,leader只可能是最后出现的那个xx。。

2)如果xx不存在,那么出现的人中,leader只可能是第一个登录的人。。

3)没出现过的人都可以是leader。。

#include <cstdio>
#include <set>

using std::set;

const int MAXN = 100000 + 10;

int n, m;
char op[MAXN];
int p[MAXN];
int sum, leader;
int firstPlus = -1, lastInfinite = -1;
bool vis[MAXN];

void Init()
{
    sum = n;
    for (int i = 1; i <= n; ++i)
    {
        vis[i] = true;
    }
}

void Read()
{
    for (int i = 1; i <= m; ++i)
    {
        getchar();
        scanf("%c%d", op + i, p + i);
        if (op[i] == '-' && vis[p[i]] == true)
        {
            lastInfinite = p[i];
        }
        if (firstPlus == -1 && op[i] == '+')
        {
            firstPlus = p[i];
        }
        if (vis[p[i]])
        {
            vis[p[i]] = false;
            --sum;
        }
    }
}

void Solve()
{
    set<int> se;

    leader = lastInfinite == -1 ? firstPlus : lastInfinite;
    if (lastInfinite != -1)
    {
        se.insert(leader);
    }
    for (int i = 1; i <= m; ++i)
    {
        if (op[i] == '+')
        {
            se.insert(p[i]);
            if (se.find(leader) == se.end())
            {
                leader = -1;
                break;
            }
        }
        else
        {
            if (!se.empty())
            {
                se.erase(p[i]);
            }
            if (!se.empty() && se.find(leader) == se.end())
            {
                leader = -1;
                break;
            }
        }
    }
    if (leader != -1)
    {
        vis[leader] = true;
        ++sum;
    }
}

void Output()
{
    printf("%d\n", sum);
    if (sum == 0) return;

    bool first = true;
    for (int i = 1; i <= n; ++i)
    {
        if (vis[i])
        {
            if (first)
            {
                first = !first;
            }
            else
            {
                printf(" ");
            }
            printf("%d", i);
        }
    }
    puts("");
}

int main()
{
    while (scanf("%d%d", &n, &m) == 2)
    {
        Init();
        Read();
        Solve();
        Output();
    }

    return 0;
}

抱歉!评论已关闭.