Codeforces Coder-Strike 2014 - Finals (online edition, Div. 1)

A. Start Up
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Recently, a start up by two students of a state university of city F gained incredible popularity. Now it's time to start a new company. But what do we call it?

The market analysts came up with a very smart plan: the name of the company should be identical to its reflection in a mirror! In other words, if we write out the name of the company on a piece of paper in a line (horizontally, from left to right) with large English letters, then put this piece of paper in front of the mirror, then the reflection of the name in the mirror should perfectly match the line written on the piece of paper.

There are many suggestions for the company name, so coming up to the mirror with a piece of paper for each name wouldn't be sensible. The founders of the company decided to automatize this process. They asked you to write a program that can, given a word, determine whether the word is a 'mirror' word or not.

Input

The first line contains a non-empty name that needs to be checked. The name contains at most 105 large English letters. The name will be written with the next sans serif font:

Output

Print 'YES' (without the quotes), if the given name matches its mirror reflection. Otherwise, print 'NO' (without the quotes).

Sample test(s)
input
AHA
output
YES
input
Z
output
NO
input
XO
output
NO


字符串和字符都是对称即可

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char s[100] = "AHIMOTUVWXY";
char t[1000100];

char in(char c)
{
    for(int i = 0; s[i]; i++)
        if(c == s[i])
            return true;

    return false;
}

bool solve()
{
    int len = strlen(t);
    for(int i = 0, j = len - 1; i < j; i++, j--)
        if(t[i] != t[j])
            return false;

    for(int i = 0; t[i]; i++)
        if(in(t[i]) == false)
            return false;

    return true;
}

int main()
{
    while(scanf("%s", t) != EOF)
    {
        if(solve()) puts("YES");
        else puts("NO");
    }
    return 0;
}


B. Online Meeting
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Nearly each project of the F company has a whole team of developers working on it. They often are in different rooms of the office in different cities and even countries. To keep in touch and track the results of the project, the F company conducts shared online meetings in a Spyke chat.

One day the director of the F company got hold of the records of a part of an online meeting of one successful team. The director watched the record and wanted to talk to the team leader. But how can he tell who the leader is? The director logically supposed that 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.

You are the assistant director. 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).

Input

The first line contains integers n and m (1 ≤ n, m ≤ 105) — the number of team participants and the number of messages. Each of the next m lines contains a message in the format:

  • 'id': the record means that the person with number id (1 ≤ id ≤ n) has logged on to the meeting.
  • 'id': the record means that the person with number id (1 ≤ id ≤ n) has logged off from the meeting.

Assume that all the people of the team are numbered from 1 to n and the messages are given in the chronological order. It is guaranteed that the given sequence is the correct record of a continuous part of the meeting. It is guaranteed that no two log on/log off events occurred simultaneously.

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.

Sample test(s)
input
5 4
+ 1
+ 2
- 2
- 1
output
4
1 3 4 5 
input
3 2
+ 1
- 2
output
1
3 
input
2 4
+ 1
- 1
+ 2
- 2
output
0
input
5 6
+ 1
- 1
- 3
+ 3
+ 4
- 4
output
3
2 3 5 
input
2 4
+ 1
- 2
+ 2
- 1
output
0


a)log中没有出现的人都是可以作为leader;

b)log中的人的第一次记录是“-”,为log之前肯定在的人;

c)log中的人的第一次记录是“+”,为log之前肯定不在的人。

思路是使用两个set in(保存肯定在的人), out(保存肯定不在的人),按照log处理,在遇到有肯定的人登录的时候,就可以把out里面的人标记为不可能成为leader,并把out clear(防止过多重复标记而导致超时)。out clear 只能清掉当前不可能成为leader的人,并不能处理之前已经被判定不可能成为leader的人,所以需要标记

最后保留在in 和out中的人都可以作为leader。

出各种问题,单个字符不会读,下回只用用scanf("%s")吧;为了考虑一种特殊情况,使用标记的方法,最后tle,其实只要直接clear就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;

const int maxn = 100110;
int n, m;
char state[maxn];
struct Data
{
    char c;
    int id;

    void input()
    {
        char t[10];
        scanf("%s %d", t, &id);
        c = t[0];
      // printf("[%c %d]\n", c, id);
        if(!state[id])
        {
            if(c == '+')
                state[id] = 1;
            else
                state[id] = 2;
        }
    }
}d[maxn];
vector<int>ans;
set<int>in, out;

void solve()
{
    in.clear();
    out.clear();
    for(int i = 1; i <= n; i++)
    if(state[i] == 2)
        in.insert(i);
    else
    if(state[i] == 1)
        out.insert(i);

    if(in.size())
    {
        for(set<int>::iterator it = out.begin(); it != out.end(); it++)
            state[*it]= -1;
        out.clear();
    }

    for(int i = 0; i < m; i++)
    {
        if(d[i].c == '+')
        {
            set<int>::iterator it = out.find(d[i].id);
            if(it != out.end())
                out.erase(it);
            in.insert(d[i].id);
        }
        else
        {
            set<int>::iterator it = in.find(d[i].id);
            if(it != in.end())
                in.erase(it);
            out.insert(d[i].id);
        }

        if(in.size())
        {
            for(set<int>::iterator it = out.begin(); it != out.end(); it++)
                state[*it]= -1;
            out.clear();
        }
    }

    for(set<int>::iterator it = in.begin(); it != in.end(); it++)
    if(state[*it] != -1)
        ans.push_back(*it);
    for(set<int>::iterator it = out.begin(); it != out.end(); it++)
    if(state[*it] != -1)
        ans.push_back(*it);
    sort(ans.begin(), ans.end());
}
int main()
{
    while(scanf("%d%d", &n, &m) == 2)
    {
        for(int i = 1; i<= n; i++)
            state[i] = 0;

        for(int i = 0; i < m; i++)
            d[i].input();

        ans.clear();
        for(int i = 1; i <= n; i++)
            if(!state[i])
                ans.push_back(i);

       solve();
        printf("%d\n", ans.size());
        int tn = ans.size() - 1;
        for(int i = 0; i <= tn; i++)
            printf("%d%c", ans[i], i == tn ? '\n' : ' ');
    }
    return 0;
}




C. Bug in Code
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Recently a serious bug has been found in the FOS code. The head of the F company wants to find the culprit and punish him. For that, he set up an organizational meeting, the issue is: who's bugged the code? Each of the n coders on the meeting said: 'I know for sure that either x or y did it!'

The head of the company decided to choose two suspects and invite them to his office. Naturally, he should consider the coders' opinions. That's why the head wants to make such a choice that at least p of n coders agreed with it. A coder agrees with the choice of two suspects if at least one of the two people that he named at the meeting was chosen as a suspect. In how many ways can the head of F choose two suspects?

Note that even if some coder was chosen as a suspect, he can agree with the head's choice if he named the other chosen coder at the meeting.

Input

The first line contains integers n and p (3 ≤ n ≤ 3·105; 0 ≤ p ≤ n) — the number of coders in the F company and the minimum number of agreed people.

Each of the next n lines contains two integers xiyi (1 ≤ xi, yi ≤ n) — the numbers of coders named by the i-th coder. It is guaranteed that xi ≠ i,  yi ≠ i,  xi ≠ yi.

Output

Print a single integer –– the number of possible two-suspect sets. Note that the order of the suspects doesn't matter, that is, sets (1, 2) и(2, 1) are considered identical.

Sample test(s)
input
4 2
2 3
1 4
1 4
2 1
output
6
input
8 6
5 6
5 7
5 8
6 2
2 1
7 3
1 3
1 4
output
1
那么大的数据规模,很容易联系扫一遍的方法,考虑到某个人的情况时,就把与他具有相同提名者的删除,然后再用树状数组统计下。

各种手贱,为了方便使用vector,结果超时了,改后,提交又超时了,担心会卡常数,就多了个数组优化下,减少使用树状数组的次数,结果还是超时了。

其实是树状数组写挫了。当初考虑树状数组的下标范围是[1,n],其实真正的下标范围是[0,n],在0的时候使用add时会超时。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;

typedef long long ll;
const int maxn = 300010;
int n, p;
int num[maxn], old[maxn];
int sum[maxn];
int first[maxn];
struct Arc
{
    int v, next;
}arc[maxn];
int cnt;

void add2(int u, int v)
{
    arc[cnt].v = v;
    arc[cnt].next = first[u];
    first[u] = cnt++;
}
void add(int i , int c)
{
    i++;
    for(; i <= n + 1; i+= i &(-i))
        sum[i] += c;
}

int ask(int i)
{
    i++;
    int ans = 0;
    for(; i > 0; i -= i &(-i))
        ans += sum[i];

    return ans;
}
ll solve()
{
    for(int i = 1;i <= n; i++)
        old[i] = num[i];
    ll ans = 0;
    for(int i = 1; i <= n; i++)
    {
        ans += i - 1 - ask(p - num[i] - 1);
        for(int j = first[i]; j + 1; j = arc[j].next)
        {
            int k = arc[j].v;
            num[k]--;
        }

        for(int j = first[i]; j + 1; j = arc[j].next)
        {
            int k = arc[j].v;
           if(old[k] == num[k]) continue;
           if(old[k] + num[i] >= p && num[k] + num[i] < p)
                ans--;

            num[k] = old[k];
        }

        add(num[i], 1);
    }

    return ans;
}
int main()
{
    while(scanf("%d%d", &n, &p) == 2)
    {
        for(int i = 1; i <= n + 1; i++)
            num[i] = sum[i] = 0, first[i] =-1;
        cnt = 0;

        for(int i = 1; i <= n; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            if(x > y)   swap(x, y);

            num[x]++;
            num[y]++;
            add2(y, x);
        }

        printf("%I64d\n", solve());
    }
    return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值