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;
}