T1:
真的有手就行,随便做一做就能过,其他人的方法应该比我的妙多了,但是我这里还是粘一下我的伪打表代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1e7 + 5;
int n, sum = 2, a[1005] = {
0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608};
int main() {
scanf("%d", &n);
if(n % 2 == 1) {
printf("-1");
return 0;
}
for(int i = 25;i >= 1; i--) {
if(n >= a[i] && a[i] != 0) {
n -= a[i];
printf("%d ", a[i]);
}
}
return 0;
}
T2:
开始打的优先队列,不过好在马上就想到了这是错解(毕竟就CCF的尿性T2会考这),后来看到了数据保证每个选手的成绩均为不超过 600 的非负整数,想到了这是一个桶排,直接从600开始向下遍历记录个数即可。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 100005;
int n, w, a[MAXN], b[MAXN], vis[MAXN];
priority_queue<int>qu;
int main() {
scanf("%d %d", &n, &w);
for(int i = 1;i <= n; i++) scanf("%d", &a[i]);
int _max = -0x3f3f3f3f;
for(int i = 1;i <= n; i++) {
int u = i * double(w) / 100;
int k = max(1, u);
vis[a[i]]++;
int o = 0;
for(int j = 600; j >= 0; j--) {