The 11th Zhejiang Provincial Collegiate Programming Contest
A.Pokemon Master
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
//FILE* _INPUT = freopen("input.txt", "r", stdin);
//FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
int n, m; rd(n), rd(m);
ll suml=0,sumr=0;
for (int i = 1; i <= n; ++i) {
ll tmp; rd(tmp);
suml+=tmp;
}
for (int i = 1; i <= m; ++i) {
ll tmp; rd(tmp);
sumr+=tmp;
}
if (suml > sumr) puts("Calem");
else if (suml == sumr) puts("Draw");
else puts("Serena");
}
return 0;
}
B.Problem Arrangement
傳送門
狀壓dp,這裡將12個問題進行二進位制壓縮,該位為0表示尚未解決,1表示已經解決;
- 用狀態壓縮的性質列舉 0 − 2 n − 1 0-2^{n-1} 0−2n−1 個狀態
- 由於點數M只有500,考慮暴力列舉點數M
- 那麼狀態方程就容易推出來了,具體詳情見程式碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 7;
const int N = (1 << 13) + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
ll dp[N][510];
int a[13][13];
ll gcd(ll x, ll y) {
if (y == 0) return x;
return gcd(y, x % y);
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
// FILE* _INPUT = freopen("input.txt", "r", stdin);
// FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
memset(dp, 0, sizeof dp);
int n, m; rd(n), rd(m);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) rd(a[i][j]);
}
dp[0][0] = 1;
for (int i = 0; i < (1 << n); ++i) {
int cnt = 0;
for (int j = 0; j < n; ++j) {
if (i & (1 << j)) ++cnt;
}
for (int j = 0; j < n; ++j) {
if (i & (1 << j)) continue;
for (int k = 0; k <= m; ++k) {
int tmp = k + a[j][cnt];
if (tmp >= m) {
dp[i ^ (1 << j)][m] += dp[i][k];
}
else dp[i ^ (1 << j)][tmp] += dp[i][k];
}
}
}
if (dp[(1 << n) - 1][m] == 0) puts("No solution");
else {
ll ans = 1;
for (int i = 1; i <= n; ++i) ans = ans * i;
ll tmp = gcd(ans, dp[(1 << n) - 1][m]);
printf("%lld/%lld\n", ans / tmp, dp[(1 << n) - 1][m] / tmp);
}
}
return 0;
}
C.Talented Chef
- 需要在最短時間內烹飪完成,顯然需要逐步的平攤時間,這個就是所需的平均時間向上取整
- 但是還要考慮一點,當一條魚的烹飪時間很長的時候,甚至是多於平均時間的時候,這時候就需要取較大的一項,即這條魚的單個烹飪時間
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 7;
const int N = 1e5 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
// FILE* _INPUT = freopen("input.txt", "r", stdin);
// FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
int n, m; rd(n), rd(m);
ll sum = 0; ll maxn = 0;
for (int i = 1; i <= n; ++i) {
int tmp; rd(tmp);
sum += tmp;
maxn = max(maxn, 1LL*tmp);
}
ll ans = sum / m;
if (sum % m) ++ans;
printf("%lld\n", max(ans,maxn));
}
return 0;
}
E.Paint the Grid Again
- 題意是刷牆有個規則,橫向只能刷黑色,縱向只能刷白色,那麼問題就好解決了
- 現在只看每一行,按照規則本應該一行都是黑色的,若出現了白色,則說明先橫向刷黑色,再縱向刷那一列的白色,即 R [ i ] − > C [ j ] , 設 該 點 坐 標 為 ( i , j ) R[i]->C[j],設該點座標為(i,j) R[i]−>C[j],設該點坐標為(i,j)
- 同樣只看每一列 ,若一列中出現黑色的,則說明 C [ j ] − > R [ i ] C[j]->R[i] C[j]−>R[i]
- 根據上述規則,進行建邊,然後跑一遍拓撲序即可
- 但答案需要輸出最小字典序,首先列 C C C字典序 < R <R <R;數字則從小到大排,所以建邊的時候,將列建邊為 j ∈ [ 1 , n ] j\in[1,n] j∈[1,n],將行建邊為 i ∈ [ n + 1 , 2 × n ] i\in[n+1,2×n] i∈[n+1,2×n]
- 最後在進行拓撲序的時候將點放進優先佇列裡,數字小的先出佇列即可
- 判斷沒有解決方案是先標記所有進行粉刷過的行和列,然後在拓撲序的時候進行新一輪標記,若有粉刷過的行或者列沒有出現在拓撲序中,則沒有解決方法,類似形成了一個環
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 7;
const int N = 1e3 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
int head[N], cnt;
struct edge {
int next, to;
}e[M];
void add(int u, int v) {
e[cnt].next = head[u];
e[cnt].to = v;
head[u] = cnt++;
}
char mp[505][505];
int degree[N];
bool row[505], col[505], vis[N];
vector<int>ans;
bool check(int n) {
memset(vis, false, sizeof vis);
priority_queue<int,vector<int>,greater<int> >que;
for (int i = 1; i <= n; ++i) {
if (col[i] && !degree[i]) {
que.push(i);
}
}
for (int i = 1; i <= n; ++i) {
if (row[i] && !degree[i+n]) {
que.push(i+n);
}
}
if (que.empty()) return 0;
while (!que.empty()) {
int u = que.top(); que.pop();
vis[u] = true;
if (u > n) {
ans.push_back(u);
vis[u] = true;
}
else {
ans.push_back(u);
vis[u] = true;
}
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (!(--degree[v])) {
que.push(v);
}
}
}
for (int i = 1; i <= n; ++i) {
if (col[i]&&!vis[i]) return false;
}
for (int i = n + 1; i <= 2 * n; ++i) {
if (row[i - n] && !vis[i]) return false;
}
for (int i = 0; i < ans.size(); ++i) {
if (ans[i] > n) {
printf("R%d", ans[i] - n);
}
else printf("C%d", ans[i]);
printf("%s", i == ans.size() - 1 ? "\n" : " ");
}
return 1;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
//FILE* _INPUT = freopen("input.txt", "r", stdin);
//FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
int n; rd(n);
memset(head, -1, sizeof head); cnt = 0;
memset(row, false, sizeof row);
memset(col, false, sizeof col);
memset(degree, 0, sizeof degree);
ans.clear();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf(" %c", &mp[i][j]);
if (mp[i][j] == 'X') row[i] = true;
else if (mp[i][j] == 'O') col[j] = true;
}
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (row[i]&&mp[i][j] == 'O') {
add(i + n, j);
++degree[j];
}
}
}
for (int j = 1; j <= n; ++j) {
for (int i = 1; i <= n; ++i) {
if (col[j]&&mp[i][j] == 'X') {
add(j, i + n);
++degree[i + n];
}
}
}
if (!check(n)) puts("No solution");
}
return 0;
}
F.Paint the Grid Reloaded
傳送門
題意:
- 一個塊上下左右相通的地方的顏色相同的即可以形成聯通塊
- 然後一個聯通塊附近必定是與他顏色相反的聯通塊
- 所以一個聯通塊反轉顏色,就必定與附近的聯通塊連線在一起,然後再反轉…
- 所以這一題首先要對圖進行縮點,然後列舉起點進行bfs來確定反轉次數,求其中的最小反轉次數
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 7;
const int N = 1e4 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
int n, m;
char mp[55][55];
bool vis[55][55];
int num[55][55];
int dir[][2] = { 1,0,-1,0,0,1,0,-1 }, cnt;
void bfs(int x,int y) {
queue<pii>que;
que.push({ x,y });
stack<pii>stk;
while (!que.empty()) {
pii p = que.front(); que.pop();
stk.push(p);
if (vis[p.first][p.second]) continue;
vis[p.first][p.second] = 1;
for (int i = 0; i < 4; ++i) {
int xx = p.first + dir[i][0], yy = p.second + dir[i][1];
if (xx <= 0 || xx > n || yy <= 0 || yy > m || vis[xx][yy] || mp[xx][yy] != mp[p.first][p.second]) continue;
que.push({ xx,yy });
}
}
++cnt;
while (!stk.empty()) {
pii p = stk.top(); stk.pop();
num[p.first][p.second] = cnt;
}
}
int head[N], cntE;
struct edge {
int next, to;
}e[M];
void add(int u, int v) {
e[cntE].to = v;
e[cntE].next = head[u];
head[u] = cntE++;
}
bool mark[N];
int bfs(int x) {
queue<pii>que;
que.push({ x,1 });
int ans = 0;
while (!que.empty()) {
pii p = que.front(); que.pop();
int u = p.first;
if (mark[u]) continue;
mark[u] = true;
ans = max(ans, p.second);
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (mark[v]) continue;
que.push({ v,p.second + 1 });
}
}
return ans-1;
}
int solve() {
memset(vis, false, sizeof vis); cnt = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (vis[i][j]) continue;
bfs(i, j);
}
}
memset(head, -1, sizeof head); cntE = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
for (int k = 0; k < 4; ++k) {
int x = i + dir[k][0], y = j + dir[k][1];
if (x <= 0 || x > n || y <= 0 || y > m) continue;
if (num[x][y] != num[i][j]) add(num[i][j], num[x][y]);
}
}
}
int minn = inf;
for (int i = 1; i <= cnt; ++i) {
for (int j = 1; j <= cnt; ++j) mark[j] = false;
minn = min(minn, bfs(i));
}
return minn;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
// FILE* _INPUT = freopen("input.txt", "r", stdin);
// FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
rd(n), rd(m);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf(" %c", &mp[i][j]);
}
}
printf("%d\n", solve());
}
return 0;
}
G.Ternary Calculation
傳送門
水題,只有三個數字的運算,直接列舉運算可能性的話也就只有25種
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 7;
const int N = 1e5 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
char s[N];
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
// FILE* _INPUT = freopen("input.txt", "r", stdin);
// FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
int a[5]; char b[5];
scanf("%d %c %d %c %d", &a[1], &b[1], &a[2], &b[2], &a[3]);
if (b[1] == '-' && (b[2] == '-' || b[2] == '+')) {
if (b[2] == '+') printf("%d\n", a[1] - a[2] + a[3]);
else printf("%d\n", a[1] - a[2] - a[3]);
continue;
}
if (b[1] == '+'||b[1]=='-') {
int ans;
if (b[2] == '+') ans = a[2] + a[3];
else if (b[2] == '-') ans = a[2] - a[3];
else if (b[2] == '*') ans = a[2] * a[3];
else if (b[2] == '/') ans = a[2] / a[3];
else ans = a[2] % a[3];
if (b[1] == '+') printf("%d\n", a[1] + ans);
else printf("%d\n", a[1] - ans);
}
else {
int ans;
if (b[1] == '*') ans = a[1] * a[2];
else if (b[1] == '/') ans = a[1] / a[2];
else ans = a[1] % a[2];
if (b[2] == '+') ans = ans + a[3];
else if (b[2] == '-') ans = ans - a[3];
else if (b[2] == '*') ans = ans * a[3];
else if (b[2] == '/') ans = ans / a[3];
else ans = ans % a[3];
printf("%d\n", ans);
}
}
return 0;
}
J.What day is that day?
傳送門
這題可以打表找規律,也可以用取模的原理,發現剛好是一個等比數列求和
L.Access System
[傳送門](Access System)
將所有時間換算成秒存起來後排序即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template <typename T>
inline void rd(T& x)
{
ll tmp = 1; char c = getchar(); x = 0;
while (c > '9' || c < '0') { if (c == '-')tmp = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
x *= tmp;
}
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
const int M = 1e7 + 10;
const double eps = 1e-8;
struct node {
int id, num;
bool friend operator<(const node& a, const node& b) {
if (a.num == b.num) return a.id < b.id;
return a.num < b.num;
}
}a[N];
vector<int>ans;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
//FILE* _INPUT = freopen("input.txt", "r", stdin);
//FILE* _OUTPUT = freopen("output.txt", "w", stdout);
int T; rd(T);
while (T--) {
int n, l; rd(n), rd(l);
ans.clear();
for (int i = 1; i <= n; ++i) {
int x, y, z;
scanf("%d:%d:%d", &x, &y, &z);
a[i].num = x * 3600 + y * 60 + z;
a[i].id = i;
}
sort(a + 1, a + 1 + n);
ans.push_back(a[1].id);
int now = a[1].num + l;
for (int i = 2; i <= n; ++i) {
if (a[i].num < now) continue;
ans.push_back(a[i].id);
now = a[i].num + l;
}
sort(ans.begin(), ans.end());
printf("%d\n%d", ans.size(),ans[0]);
for (int i = 1; i < ans.size();++i) {
printf(" %d", ans[i]);
}
puts("");
}
return 0;
}
相關文章
- The 2024 CCPC Shandong Invitational Contest and Provincial Collegiate Programming Contest
- 2021 Hubei Provincial Collegiate Programming Contest/2021湖北省賽 題解
- 2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming ContestACM
- 2023 Hubei Provincial Collegiate Programming Contest題解 C F H I J K M
- 2024 Jiangsu Collegiate Programming Contest
- 2024年3月20日 VP[The 13th Shandong ICPC Provincial Collegiate Programming Contest]
- 2022 International Collegiate Programming Contest, Jinan SiteNaN
- 2020 China Collegiate Programming Contest Qinhuangdao Site
- The 2022 ICPC Polish Collegiate Programming Contest (AMPPZ 2022)
- 2022 China Collegiate Programming Contest (CCPC) Guilin SiteGUI
- The 8th Hebei Collegiate Programming Contest: F - 3 Split
- 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)
- 2022 China Collegiate Programming Contest (CCPC) Mianyang Onsite E Hammer to Fall
- The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners
- 2024 (ICPC) Jiangxi Provincial Contest -- Official Contest
- The 16th Zhejiang Provincial (小白 重現之我是Joker)
- AISing Programming Contest 2021(AtCoder Beginner Contest 202)AI
- Mynavi Programming Contest 2021(AtCoder Beginner Contest 201)
- 2024 BUPT Programming Contest F
- Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)
- KEYENCE Programming Contest 2024(AtCoder Beginner Contest 374)題解
- Toyota Programming Contest 2024#7(AtCoder Beginner Contest 362)
- Toyota Programming Contest 2024#3(AtCoder Beginner Contest 344)
- UNIQUE VISION Programming Contest 2024 Spring(AtCoder Beginner Contest 346)Spring
- North American Invitational Programming Contest 2018
- The 2022 ICPC Asia Hangzhou Regional Programming Contest
- Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)題解
- Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)題解A~D
- Hitachi Vantara Programming Contest 2024(AtCoder Beginner Contest 368)F - Dividing GameGAM
- 2020-2021 “Orz Panda” Cup Programming Contest
- Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)題解總結
- 2024.10.3 2022-2023 ICPC Brazil Subregional Programming Contest
- Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 383)題解AI
- TOYOTA SYSTEMS Programming Contest 2024(AtCoder Beginner Contest 377) 補題記錄(A-E)
- 2022 Benelux Algorithm Programming Contest (BAPC 22) A 、I、J、LUXGo
- The 2024 Hunan Multi-School Programming Training Contest, Round 4NaNAI
- [ABC 346] UNIQUE VISION Programming Contest 2024 Spring 題解Spring
- 2018 BACS Regional Programming Contest C. BACS, Scoundrel Shopkeeper and Contiguous Sequence (模擬)