中规中矩的一场。
题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=855
C:
定义函数f(d,k)为数字d在数字k中出现的次数。给定d和x,找到尽量大的k使得k<=x且f(d,k)==k。
很诡异的一题,最好的做法仍然是打表找规律。题解给了一个很神奇的结论:满足条件的k<1011且k的分布非常稀疏。

1 /* basic header */
2 #include <bits/stdc++.h>
3 /* define */
4 #define ll long long
5 #define dou double
6 #define pb emplace_back
7 #define mp make_pair
8 #define sot(a,b) sort(a+1,a+1+b)
9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson (curpos<<1)
15 #define rson (curpos<<1|1)
16 /* namespace */
17 using namespace std;
18 /* header end */
19
20 const ll m = 1e5, maxn = 1e6 + 10;
21 ll a[maxn][10], ans[10][maxn], cnt[10];
22
23 bool check(ll x, ll y) {
24 if (x < 0 && y >= 0) return 1;
25 if (x > y && x >= 0 && x < m) return 1;
26 return 0;
27 }
28
29 int main() {
30 for (int i = 1; i < m * 10; i++) {
31 for (int j = 0; j < 10; j++) a[i][j] = a[i / 10][j];
32 a[i][i % 10]++;
33 }
34 for (int d = 1; d < 10; d++) {
35 int r = 1;
36 for (int i = 0; i < m * d; i++)
37 if (check(r, r - m / 2 + m * a[i][d])) {
38 for (int j = 0; j < m; j++) {
39 r += a[i][d] + a[j][d] - 1;
40 if (!r) ans[d][cnt[d]++] = m * i + j;
41 }
42 } else r += m * a[i][d] - m / 2;
43 }
44 int query; scanf("%d", &query);
45 while (query--) {
46 int d; ll k; scanf("%d%lld", &d, &k);
47 int r = cnt[d] - 1;
48 while (r >= 0 && ans[d][r] > k) r--;
49 if (r >= 0) printf("%lld\n", ans[d][r]);
50 else puts("0");
51 }
52 return 0;
53 }
I:
给定两个矩形的左上角和右下角坐标,问这两个矩形把平面分成几个区域。
离散化是重点。

/* Codeforces Contest 2019_mutc_08
* Problem I
* Au: SJoshua
*/
#include <set>
#include <unordered_map>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
bool board[20][20];
const int movement[4][2] = {
{0, -1}, {0, 1}, {1, 0}, {-1, 0}
};
struct node {
int x, y;
};
struct Rectangle {
int x1, y1, x2, y2;
void fill(void) {
for (int x = x1; x <= x2; x++) {
board[x][y1] = board[x][y2] = true;
}
for (int y = y1; y <= y2; y++) {
board[x1][y] = board[x2][y] = true;
}
}
};
void init(void) {
memset(board, 0, sizeof(board));
}
int calc(void) {
int ans = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
if (!board[i][j]) {
queue <node> info;
info.push({i, j});
while (!info.empty()) {
auto t = info.front();
info.pop();
if (board[t.x][t.y]) {
continue;
}
board[t.x][t.y] = true;
for (int k = 0; k < 4; k++) {
int nx = t.x + movement[k][0], ny = t.y + movement[k][1];
if (0 <= nx && nx < 20 && 0 <= ny && ny < 20 && !board[nx][ny]) {
info.push({nx, ny});
}
}
}
ans++;
}
}
}
return ans;
}
int main(void) {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int T;
cin >> T;
while (T--) {
vector <int> vec(8);
set <int> hash;
unordered_map <int, int> mp;
for (int i = 0; i < 8; i++) {
cin >> vec[i];
hash.insert(vec[i]);
}
int cur = 1;
for (auto e : hash) {
mp[e] = cur;
cur += 2;
}
Rectangle A = {mp[vec[0]], mp[vec[1]], mp[vec[2]], mp[vec[3]]};
Rectangle B = {mp[vec[4]], mp[vec[5]], mp[vec[6]], mp[vec[7]]};
init();
A.fill();
B.fill();
cout << calc() << endl;
}
return 0;
}
J:
签到题,水题。

1 /* Codeforces Contest 2019_mutc_08
2 * Problem J
3 * Au: SJoshua
4 */
5 #include <cstdio>
6 #include <vector>
7 #include <string>
8 #include <iostream>
9 #include <algorithm>
10
11 using namespace std;
12
13 struct info {
14 string name;
15 int score, penalty;
16 };
17
18 int main(void) {
19 std::ios::sync_with_stdio(false);
20 std::cin.tie(0);
21 int T;
22 cin >> T;
23 while (T--) {
24 int n, d;
25 cin >> n >> d;
26 vector <info> board(n);
27 for (int i = 0; i < n; i++) {
28 cin >> board[i].name >> board[i].score >> board[i].penalty;
29 }
30 sort(board.begin(), board.end(), [](info & a, info & b)->bool {
31 return a.score == b.score ? a.penalty < b.penalty : a.score > b.score;
32 });
33 d *= 10;
34 if ((n * d) % 100 == 50) {
35 cout << board[(n * d) / 100].name << endl;
36 } else {
37 cout << "Quailty is very great" << endl;
38 }
39 }
40 return 0;
41 }
K:
有n个班级,一个班有ai个人并准备了bi杯奶茶。每个人只能喝一杯奶茶,而且不能喝本班的奶茶。问最多有多少人能喝奶茶。
按班级人数从大到小排序,然后对于第i个班,从第i+1个班开始绕一圈喝奶茶即可。

1 /* Codeforces Contest 2019_mutc_08
2 * Problem K
3 * Au: SJoshua
4 */
5 #include <queue>
6 #include <cstdio>
7 #include <vector>
8 #include <string>
9 #include <list>
10 #include <iostream>
11 #include <algorithm>
12
13 using namespace std;
14
15 struct _Class {
16 int num, tea;
17 };
18
19 int main(void) {
20 std::ios::sync_with_stdio(false);
21 std::cin.tie(0);
22 int T; cin >> T;
23 while (T--) {
24 int n; cin >> n;
25 vector <_Class> _class(n);
26 for (int i = 0; i < n; i++) {
27 cin >> _class[i].num >> _class[i].tea;
28 }
29 sort(_class.begin(), _class.end(), [](_Class & a, _Class & b) {
30 return a.tea == b.tea ? a.num > b.num : a.tea > b.tea;
31 });
32 long long int ans = 0;
33 vector <int> nxt(n);
34 for (int i = 0; i < n - 1; i++) nxt[i] = i + 1;
35 nxt[n - 1] = 0;
36 for (int i = 0; i < n; i++) {
37 int nxt = i;
38 long long int cnt = 0, round = 0;
39 while (_class[i].num) {
40 round++;
41 int last = nxt; nxt = nxt[nxt];
42 if (nxt == i) break;
43 if (_class[nxt].tea) {
44 int drink = min(_class[nxt].tea, _class[i].num);
45 _class[i].num -= drink, _class[nxt].tea -= drink;
46 ans += drink, cnt += drink;
47 } else nxt[last] = nxt[nxt];
48 if (round > n) break;
49 }
50 if (!cnt && _class[i].num) break;
51 }
52 cout << ans << endl;
53 }
54 return 0;
55 }
