A.Ichihime and Triangle
题意:
给定四个数,要求确定
使其构成三角形的三条边,
题解:
令三个数为即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
void solve()
{
ll a, b, c, d;
scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
printf("%lld %lld %lld\n", b, c, c);
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} B.Kana and Dragon Quest game
题意:
给一个数,你可以进行两种操作:
问能否通过至多次操作
和至多
次操作
使得
题解:
令,得
,因此当
时进行操作
反而会使
变大,所以先将
通过操作
尽可能的降至
且最小的位置,再用操作
判断其是否会
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
void solve()
{
int h, n, m;
scanf("%d%d%d", &h, &n, &m);
while (h > 20 && n)
{
n--;
h = h / 2 + 10;
}
puts(h <= m * 10 ? "YES" : "NO");
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} C.Linova and Kingdom
题意:
给定个节点
条边组成且以节点
为根的树,
现需要选出个节点作为工业城市,其余城市均为旅游城市
问从所有工业城市出发走到根节点所经过的旅游城市数量之和的最大值
题解:
首先可以发现贪心将所有深度尽可能大的节点染成白色是最优的,但是要算最大值所以还需要确定具体的值,如果只取深度最大的个因为无法确定其父节点是否也为工业城市,所以这个贪心策略不行。考虑到如果加入一个节点的话,那么它的儿子节点肯定已经记为工业城市,所以这个点的贡献就是
,所以可以算出每个节点的
,取前
大个即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
vector<int> G[maxn], v;
int dfs(int u, int f, int dep)
{
int son = 1;
for (auto v : G[u])
{
if (v == f)
continue;
son += dfs(v, u, dep + 1);
}
v.push_back(dep - son + 1);
return son;
}
int main()
{
int n, k;
scanf("%d%d", &n, &k);
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, 0, 0);
sort(v.rbegin(), v.rend());
printf("%lld\n", accumulate(v.begin(), v.begin() + k, 0ll));
return 0;
} D.Xenia and Colorful Gems
题意:
给定三种数字,三种数字分别有
个,现在要在每种数字中取出
个,使得
最小
题解:
枚举其中一种数,另外两种二分找最接近的即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
inline ll calc(ll x, ll y, ll z) { return (x - y) * (x - y) + (y - z) * (y - z) + (z - x) * (z - x); }
int n[3], v[3][maxn], p[3] = {0, 1, 2};
void solve()
{
scanf("%d%d%d", &n[0], &n[1], &n[2]);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < n[i]; j++)
scanf("%d", &v[i][j]);
sort(v[i], v[i] + n[i]);
}
ll ans = 6e18 + 10;
do
{
for (int i = 0; i < n[p[0]]; i++)
{
int pos1 = lower_bound(v[p[1]], v[p[1]] + n[p[1]], v[p[0]][i]) - v[p[1]];
int pos2 = upper_bound(v[p[2]], v[p[2]] + n[p[2]], v[p[0]][i]) - v[p[2]];
if (pos1 != n[p[1]] && pos2 != 0)
ans = min(ans, calc(v[p[0]][i], v[p[1]][pos1], v[p[2]][pos2 - 1]));
}
} while (next_permutation(p, p + 3));
printf("%lld\n", ans);
}
int main()
{
int t;
for (scanf("%d", &t); t >= 1; t--)
solve();
} E.Kaavi and Magic Spell
题意:
给定一个长度为的字符串
和一个长度为
的字符串
,其中
。
现有一个空串,可以对
进行至多
次操作,一共有两种不同的操作,操作如下:
- 将
的首部添加到
的首部,并从
中删除
- 将
的首部添加到
的尾部,并从
中删除
询问有多少中不同的操作组合可以使得的前缀等于
,输出所有的操作组合数,长度不同或者是操作序列中有某个地方不同可视为是不同的操作。
题解:
区间。
描述当前和
在区间
的匹配个数。这里将
长度扩展为
,但是从
之后的顺序是任意的。
转移方程:
注意到插入空串的时候前后算是两种,所以没必要特殊处理,把初始化成
就可以了。
最终所求就是的总和。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 3005;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
char S[maxn], T[maxn];
ll dp[maxn][maxn];
int main()
{
scanf("%s%s", S + 1, T + 1);
int n = strlen(S + 1), m = strlen(T + 1);
for (int i = 1; i < maxn; i++)
dp[i][i - 1] = 1;
for (int i = 1; i <= n; i++)
for (int l = 1, r = l + i - 1; r <= n; l++, r++)
{
if (l > m || S[i] == T[l])
dp[l][r] = (dp[l][r] + dp[l + 1][r]) % mod;
if (r > m || S[i] == T[r])
dp[l][r] = (dp[l][r] + dp[l][r - 1]) % mod;
}
ll ans = 0;
for (int i = m; i <= n; i++)
ans = (ans + dp[1][i]) % mod;
printf("%lld\n", ans);
return 0;
} 
京公网安备 11010502036488号