人菜,只会 T1,T2,T3 调了半天 dijkstra。。。
T1:
暴力题一道;枚举出 $x,y$,接着再算 $z$ 是否存在即可。
#include <bits/stdc++.h>
using namespace std;
signed main()
{
int T;
scanf ("%d", &T);
while (T --)
{
bool f = 0;
int n;
scanf ("%d", &n);
for (int i = 0; i * 3 <= n && !f; i ++) //3x 绝对不可能 > n
for (int j = 0; j * 5 + i * 3 <= n; j ++) // 3x+5y 也不能 > n
{
int x = j * 5 + i * 3; // 减去两数后的差
if ((n - x) % 7) continue; // 若差不能被 7 整除则跳过
f = 1;
printf ("%d %d %d\n", i, j, (n - x) / 7);// (n-x)/7 为 z
break;
}
if (!f)
puts ("-1");
}
return 0;
}
T2
相对于前两次的 T2,这明显良心了很多;
算法:贪心;
策略:取最大值,接着在操作允许的情况下每次加上所剩序列中的最大值。可以用大根堆来实现。
#include <bits/stdc++.h>
using namespace std;
int n, m;
priority_queue <int, vector <int>, greater <int>> q;
void solve()
{
int res = 0;
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; i ++)
{
int x;
scanf ("%d", &x);
q.push (x);
res = max (res, x); // 取最大值
}
q.pop();
while (q.size() && m) // 操作不允许情况有两种:1.序列已空;2.次数已尽
{
m --;
res += q.top();
q.pop();
}
printf ("%d\n", res);
return ;
}
signed main()
{
int T;
scanf ("%d", &T);
while (T --)
{
solve();
}
return 0;
}
注明:
这是笔记,不是题解,只是板块漂移了亿点点。