这场咋全是结论题啊?
A - Payment
难得有心情写A的题解
就一思博题,是1000的倍数就输出0不是就输出最近的1000的倍数减去它。
#include
using namespace std;
int n;
int main() {
scanf("%d", &n);
if (n % 1000 == 0) cout << 0;
else cout << n / 1000 * 1000 + 1000 - n;
return 0;
}
B - Judge Status Summary
map统计一遍就好。
#include
using namespace std;
int n;
map mp;
string s;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s;
mp[s]++;
}
cout << "AC x " << mp["AC"] << endl;
cout << "WA x " << mp["WA"] << endl;
cout << "TLE x " << mp["TLE"] << endl;
cout << "RE x " << mp["RE"] << endl;
return 0;
}
C - H and V
刚一看题觉得这题很难,然后看一下数据范围...暴力就行
#include
using namespace std;
int n, m, T;
char mp[10][10];
bool mark[10][10];
int ans;
int main() {
cin >> n >> m >> T;
for (int i = 1; i <= n; i++) {
scanf("%s", mp[i] + 1);
}
for (int i = 0; i < (1 << n); i++) {
for (int j = 0; j < (1 << m); j++) {
memset(mark, 0, sizeof(mark));
for (int k = 0; k < n; k++) {
if ((i >> k) & 1) {
for (int l = 1; l <= m; l++) {
mark[k + 1][l] = 1;
}
}
}
for (int k = 0; k < m; k++) {
if ((j >> k) & 1) {
for (int l = 1; l <= n; l++) {
mark[l][k + 1] = 1;
}
}
}
int cnt = 0;
for (int k = 1; k <= n; k++) for(int l = 1; l <= m; l++) if (!mark[k][l] && mp[k][l] == '#') cnt++;
if (cnt == T) ans++;
}
}
cout << ans;
return 0;
}
D - Chat in a Circle
不错的贪心题,按从大到小的排序,除了最大的其它都可以取两遍,取前n-1大即可。
#include
using namespace std;
typedef long long ll;
const int N = 200010;
int n;
ll ans;
int a[N];
queue q;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
q.push(a[n]);
for (int i = n - 1; i; i--) {
q.push(a[i]);
q.push(a[i]);
}
for (int i = 1; i < n; i++) {
ans += q.front();
q.pop();
}
cout << ans;
return 0;
}
E - Multiplication 4
又是贪心题。考场想歪浪费了好多时间。
先按abs排序取前k大然后看看是不是负数,如果是再考虑换一个数比较一下就行。
#include
using namespace std;
typedef long long ll;
const int N = 200010;
const ll mod = 1e9 + 7;
struct node{
ll val, f;
friend bool operator < (node x, node y) {
return x.val * x.f < y.val * y.f;
}
};
int n, k, tmp;
ll a[N], ans = 1;
priority_queue q1, q2;
ll s1[N], s2[N], top1, top2;
int main() {
cin >> n >> k;
tmp = k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[i] > 0) q1.push(node{a[i], 1});
else q2.push(node{a[i], -1});
}
while (k) {
if (!q1.empty() && !q2.empty()) {
node x = q1.top();
q1.pop();
node y = q2.top();
q2.pop();
if (x.val * x.f > y.val * y.f) {
s1[++top1] = x.val;
q2.push(node{y.val, y.f});
} else {
s2[++top2] = y.val;
q1.push(node{x.val, x.f});
}
} else if (!q1.empty()) {
node x = q1.top();
q1.pop();
s1[++top1] = x.val;
} else if (!q2.empty()) {
node x = q2.top();
q2.pop();
s2[++top2] = x.val;
}
k--;
}
if (top2 % 2) {
if (top1) {
if (!q1.empty() && !q2.empty()) {
if (q2.top().val * s2[top2] > q1.top().val * s1[top1]) {
top1--;
s2[++top2] = q2.top().val;
} else {
top2--;
s1[++top1] = q1.top().val;
}
} else if (!q1.empty()) {
top2--;
s1[++top1] = q1.top().val;
} else if (!q2.empty()) {
top1--;
s2[++top2] = q2.top().val;
}
} else {
if (!q1.empty()) {
top2--;
s1[++top1] = q1.top().val;
} else {
sort(a + 1, a + n + 1);
top2 = 0;
for (int i = n; i >= n - tmp + 1; i--) {
s2[++top2] = a[i];
}
}
}
}
for (int i = 1; i <= top1; i++) ans = (ans * s1[i]) % mod;
for (int i = 1; i <= top2; i++) ans = (ans * s2[i]) % mod;
cout << (ans % mod + mod) % mod;
return 0;
}
F - Intervals on Tree
又是结论题。
我们发现对于一条边它会把两个端点的连通块变成一个,所以先把树看成没有边的,每一条边减去有多少个区间包含其即可。
#include
using namespace std;
typedef long long ll;
const int N = 200010;
const ll mod = 1e9 + 7;
int n;
ll ans;
int main() {
cin >> n;
for (ll i = 1; i <= n; i++) ans += i * (n - i + 1);
for (int i = 1; i < n; i++) {
ll u, v;
cin >> u >> v;
if (u > v) swap(u, v);
ans -= u * (n - v + 1);
}
cout << ans;
return 0;
}