A - Cut
题意
签到题
思路
代码
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int n, k;
scanf("%d%d", &n, &k);
vector<int> v(n);
for (int i = 0; i < n; i++)
{
scanf("%d", &v[i]);
}
for (int i = n - k; i < n; i++)
{
printf("%d ", v[i]);
}
for (int i = 0; i < n - k; i++)
{
printf("%d ", v[i]);
}
}
int main()
{
int T = 1;
// scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
B - Decrease 2 max elements
题意
签到题
思路
数据很小,直接模拟。
其实是一个很经典的贪心算法,算的就是每次任意选两个正数减 1,最多能减多少次,而这个问题的答案就是min(sum / 2, sum - maxn)。
代码一
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int mxn = 1e6 + 5;
void solve()
{
int n;
scanf("%d", &n);
vector<int> v(n);
for (int i = 0; i < n; i++)
{
scanf("%d", &v[i]);
}
int ans = 0;
while (true)
{
sort(v.begin(), v.end(), greater<int>());
if (v[1] <= 0)
{
break;
}
v[0]--;
v[1]--;
ans++;
}
printf("%d", ans);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
//scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
代码二
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
const int mxn = 1e6 + 5;
void solve()
{
int n, sum = 0, maxn = -1;
scanf("%d", &n);
vector<int> v(n);
for (int i = 0; i < n; i++)
{
scanf("%d", &v[i]);
sum += v[i];
maxn = max(maxn, v[i]);
}
printf("%d", min(sum / 2, sum - maxn));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
//scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}
C - Triple Attack
题意
n个人,第i个人的血量是h_i,t从0开始计数,每次操作t++,t是3的倍数扣3点血,否则扣1点血。求使所有人血量<=0的操作数。
思路
每3次为一循环,每轮循环扣5点血,超出一次循环的部分可以直接计算,剩下的至多模拟2次即可。
代码
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mxn = 1e6 + 5;
void solve()
{
int n;
scanf("%lld", &n);
vector<int> v(n);
for (int i = 0; i < n; i++)
{
scanf("%lld", &v[i]);
}
int ans = 0;
for (int i = 0; i < n; i++)
{
ans += v[i] / 5 * 3;
v[i] %= 5;
while (v[i] > 0)
{
ans++;
v[i] -= (ans % 3 ? 1 : 3);
}
}
printf("%lld", ans);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
//scanf("%lld", &T);
while (T--)
{
solve();
}
return 0;
}
D - Minimum Steiner Tree
题意
给定一棵n条边的树,以及k个点,删点删边使得剩下的点中包含所给的k个点,问剩下结点数的最小值。
思路
从一个要保留的点出发,以各最终要保留点为根分治每颗子树,将各自要保留的点数相加。
(感觉树的题大部分是dfs?