ZAFUACM - 7.10个人赛补题 A - C & E & H

A - 黑崎x护 - CodeForces 501B

题目链接

题意

给出任意组数据,每组包含两个字符串,当 A 组的第二个字符串等于 B 组的第一个字符串时,将 A 组的第一个字符串转换成 B 组的第二个字符串,输出全部转换后还剩多少组数据,每组数据分别是什么

思路

二重循环,每修改一次就把被修改的那一组做个标记(我是把被修改的那组的第一个字符串换成‘ ’表示这一组一会儿不用输出了)

代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1010;

int q;
string s[N][2];
string ans[N][2];
int num;

int main()
{
    cin >> q;
    for (int i = 0; i < q; i ++ )
        cin >> s[i][0] >> s[i][1];
    for (int i = 0; i < q; i ++ )
    {
        if (s[i][0] != " ")
        {
            string ss = s[i][1];
            for (int j = i + 1; j < q; j ++ )
            {
                if (ss == s[j][0])
                {
                    s[j][0] = " ";
                    ss = s[j][1];
                }
            }
            ans[num][0] = s[i][0];
            ans[num][1] = ss;
            num ++ ;
        }
    }
    cout << num << endl;
    for (int i = 0; i < num; i ++ )
    {
        cout << ans[i][0] << ' ' << ans[i][1] << endl;
    }
    return 0;
}

B - 中野x乃 - CodeForces 519C

题目链接

题意

分组每组三个人,必须是一个大佬 + 两个菜鸡 or 一个菜鸡 + 两个大佬,给出大佬菜鸡的人数,问最多能组多少队

思路

贪心,每次判断大佬和菜鸡人数多少,当前大佬多就选2大佬1菜鸡,否则相反

代码

#include <iostream>
#include <algorithm>

using namespace std;

int n, m;
int ans;

int main()
{
    cin >> n >> m;
    if (n == 1 && m == 1)
    {
        cout << 0;
        return 0;
    }
    if (m >= 2 * n) cout << n;
    else
    {
        if (n >= 2 * m) cout << m;
        else
        {
            while (1)
            {
                if (n >= m)
                {
                    n -= 2;
                    m -= 1;
                    ans ++ ;
                }
                else
                {
                    n -= 1;
                    m -= 2;
                    ans ++ ;
                }
                if (n == 0 || m == 0 || (n == 1 && m == 1)) break;
            }
            cout << ans;
        }
    }
    return 0;
}

C - x笠·阿克曼 - CodeForces 501C

题目链接

题意

给出点的个数,每个点给出两个信息 d 和 s,d 表示度,s 表示与该点相邻的所有点的异或和,问这个图长啥样

思路

参考了某大佬的代码,先找到所有度为 1 的点,这些点的 s 就等于该点的邻接点,然后修改邻接点的 d 和 s,继续操作直到没有度为 1 的点

代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

int main()
{
    int n; cin >> n;
    vector<int> d(n);
    vector<int> s(n);
    for (int i = 0; i < n; i ++ )
    {
        cin >> d[i] >> s[i];
    }
    queue<int> q;
    for (int i = 0; i < n; i ++ )
    {
        if (d[i] == 1) q.push(i);
    }
    vector<PII> g;
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        if (d[t] == 1)
        {
            g.push_back({t, s[t]});
            int u = s[t];
            s[u] ^= t;
            d[u] -- ;
            if (d[u] == 1) q.push(u);
        }
    }
    cout << g.size() << endl;
    for (int i = 0; i < g.size(); i ++ )
    {
        cout << g[i].first << ' ' << g[i].second << endl;
    }
}

E - x条悟 - CodeForces 405D

题目链接

题意

给定 s = 1e6,给出若干个 x,要求 Σ(x - 1) = Σ(s - y),x y 不能重复,输出 y 的数量和 y 的值

思路

i 对应的就是 s - i + 1 ,如果这个值不在 x 中,直接输出,如果在,就输出两个等距离的没被用过的

代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 1000010;
const int s = 1e6;

int n;
int x[N];
bool st[N];
vector<int> available;
int need;

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ )
    {
        cin >> x[i];
        st[x[i]] = true;
    }
    cout << n << endl;
    for (int i = 1; i <= 1000000 / 2; i ++ )
    {
        if (!st[i] && !st[s - i + 1]) available.push_back(i);
        else if (st[i] && !st[s - i + 1]) cout << s - i + 1 << ' ';
        else if (!st[i] && st[s - i + 1]) cout << i << ' ';
        else need ++ ;
    }
    for (int i = 0; i < need; i ++ )
    {
        cout << available[i] << ' ' << s + 1 - available[i] << ' ';
    }
}

H - 比企谷x幡 - CodeForces 710E

题目链接

题意

一个人只会打一个字母,添加或删除一个字母耗时 x,复制已经写过的耗时 y,这个人一共要打 n 个字母,问最短耗时

思路

这题赛时耗了好久,开始摆烂,最后一分钟改了个炸裂的写法提交了,居!然!AC!了!
(炸裂的写法放在最后)

接下来是参考的大佬的思路:贪心,分奇偶讨论,具体看代码吧~

代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

using i64 = long long;
const i64 inf = 0x3f3f3f3f3f3f;

int main()
{
    int n, x, y; cin >> n >> x >> y;
    vector<i64> f(n + 1, inf);
    f[0] = 0;
    for (int i = 1; i <= n; i ++ )
    {
        f[i] = min(f[i], f[i - 1] + x);
        if (i & 1) f[i] = min({f[i], f[(i - 1) / 2] + y + x, f[(i + 1) / 2] + x + y});
        else f[i] = min(f[i], f[i / 2] + y);
    }
    cout << f[n];
}

已经不知道自己怎么会这么写的代码了…

#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

typedef long long LL;

int n, x, y;
vector<LL> cost;

int main()
{
    cin >> n >> x >> y;
    cost.push_back(0);
    cost.push_back(x);
    for (int i = 2; i <= N; i ++ )
    {
        if (i % 2 == 0)
        {
            cost.push_back(min(cost[i / 2] + y, cost[i - 1] + x));
        }
        else cost.push_back(cost[i - 1] + x);
    }
    bool flag = false;
    int idx = 1;
    while (flag || idx)
    {
        idx = 0;
        flag = false;
    	for (int i = N - 1; i >= 1; i -- )
    	{
        	if (cost[i] > cost[i + 1] + x)
        	{
            	cost[i] = cost[i + 1] + x;
            	flag = true;
        	}
    	}
    	for (int i = 2; i <= N; i ++ )
    	{
        	if (i % 2 == 0)
        	{
            	if (cost[i] > cost[i / 2] + y)
            	{
                	cost[i] = cost[i / 2] + y;
                	flag = true;
            	}
            	if (cost[i] > cost[i - 1] + x)
            	{
                	cost[i] = cost[i - 1] + x;
                	flag = true;
            	}
        	}
        	else
        	{
            	if (cost[i] > cost[i - 1] + x)
            	{
                	cost[i] = cost[i - 1] + x;
                	flag = true;
            	}
        	}
    	}
    }
    cout << cost[n];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Texcavator

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值