Codeforces Round #445【solved:4 / 7】

地址:http://codeforces.com/contest/890
A. ACM ICPC

给你6个数字,能否凑成两组,和相等。

#include <bits/stdc++.h>
using namespace std;

int a[6], sum = 0;
bool solve()
{
    do
    {
        int cnt = 0;
        for(int i = 0; i < 3; i++)  cnt+=a[i];
        if(cnt * 2 == sum)  return true;
    }while(next_permutation(a, a + 6));
    return false;
}
int main()
{
    for(int i = 0; i < 6; i++)  scanf("%d", &a[i]), sum += a[i];
    sort(a, a + 6);
    if(solve()) puts("YES");
    else puts("NO");
    return 0;
}

B. Vlad and Cafes

给你十万个数,问你从后往前数最早的一个 使得n个数字里面所有数字都出现过至少一次的 数字是几。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

int a[maxn];
set<int>s;

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        s.insert(a[i]);
    }
    int m = s.size();
    s.clear();
    for(int i = n - 1; i >= 0; i --)
    {
        s.insert(a[i]);
        if(s.size() == m)
        {
            printf("%d\n", a[i]);
            break;
        }
    }
    return 0;
}

C. Petya and Catacombs(贪心)

给你十万个时间点,每个时间点i出现在一个房间里。如果是出现在曾经去过的房间里,则写下上一次到达这个房间的时间点,否则随机写一个小于当前时间i的数字。问你至少需要去几个不同的房间能满足给出的时间点序列。

思路:贪心一下,每次尽量去去过的房间,不够用的时候加一个就行了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

int a[maxn];
map<int, int>ma;

int main()
{
    int n;
    scanf("%d", &n);
    int cnt = 0;
    for(int i = 1; i <= n; i++)
    {
        int x;
        scanf("%d", &x);
        if(ma[x])
        {
            ma[x] = 0;
            ma[i] = 1;
        }
        else if(ma[x] == 0)
        {
            ma[i] = 1;
            cnt++;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

D. Restoration of string(拓扑排序)

给出十万个字符串,总长度不超过十万,要求构造一个字符串,使得所有给出的字符串在这个串当中都是出现次数最多子串。输出长度最短的答案。如果有多个答案,输出字典序最小的。

思路:
  把每个给出的字符串中,相邻的两个字符连上一条有向边。
  首先我们要知道,如果有解,那么这个解应该是若干条链贪心加和。所以出现环则无解。
  其次每个点的出入度最大只能为1,否则无法满足题意。
  最后要注意处理单个字符的情况。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

char str[maxn];
int vis[maxn], out[maxn], in[maxn], input[maxn];
vector<string>vec;
vector<int>G[maxn];
string temp;
int ok;
void dfs(int cur)
{
    if(ok == 0) return ;
    vis[cur] = 1;
    temp += 'a' + cur;
    for(auto v : G[cur])
    {
        if(vis[v])  ok = 0;
        dfs(v);
    }
}

bool solve()
{
    for(int i = 0; i < 26; i++)
    {
        out[i] += G[i].size();
        for(auto o : G[i])  in[o]++;
    }

    for(int i = 0; i < 26; i++)
    {
        if(in[i] > 1 || out[i] > 1) return false;
    }

    for(int i = 0; i < 26; i++)
    {
        ok = 1;
        temp = "";
        if(in[i] == 0 && out[i])    dfs(i);
        vec.push_back(temp);
        if(ok == 0) return false;
    }

    for(int i = 0; i < 26; i++)
    {
        if(vis[i] == 0 && in[i])    return false;

        if(vis[i] == 0 && input[i])
        {
            string t = "";
            t += ('a' + i);
            vec.push_back(t);
        }
    }
    sort(vec.begin(), vec.end());

    string ans = "";
    for(auto o : vec)   ans += o;
    cout << ans << endl;
    return true;
}
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", str);
        int len = strlen(str);
        if(len == 1)    input[str[0] - 'a'] = 1;
        else
        {
            for(int j = 0; j < len - 1; j++)
            {
                int lb = str[j] - 'a', rb = str[j + 1] - 'a';
                G[lb].push_back(rb);
            }
        }
    }
    for(int i = 0; i < 26; i++)
    {
        sort(G[i].begin(), G[i].end());
        G[i].resize(unique(G[i].begin(), G[i].end()) - G[i].begin());
    }

    if(solve() == 0)    puts("NO");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_29556211/article/details/78561341