2021年CCCC-总决赛

1-1

print("To iterate is human, to recurse divine.")

1-2

#include <bits/stdc++.h>

using namespace std;

int n, m, k;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m >> k;
	cout << max(n - m * k, 0);
	return 0;
} 

1-3

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

int n, m, k;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	string s;
	cin >> s;
	if (s.size() == 6) {
		cout << s.substr(0, 4) << '-' << s.substr(4, 2) << endl;
	} else {
		string x = s.substr(0, 2);
		if (x < "22") cout << "20";
		else cout << "19";
		cout << s.substr(0, 2) << '-' << s.substr(2, 2) << endl;
	}
	return 0;
} 

1-4

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

int n, m, k;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	double a;
	cin >> n >> m;
	while (n--) {
		cin >> a;
		if (a < m) {
			cout << "On Sale! " << a << endl;
		}
	}
	return 0;
} 

1-5

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

int n, m, k;
int a[50];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	for (int i = 0; i <= 23; ++i) {
		cin >> a[i];
	}
	while (cin >> m) {
		if (m < 0 || m > 23) break;
		cout << a[m];
		if (a[m] > 50) {
			cout << " Yes" << endl;
		} else {
			cout << " No" << endl;
		}
	}
	return 0;
} 

1-6

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

int n, m, k;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	string s;
	cin >> n >> m;
	getline(cin, s);
	for (int i = 1; i <= n; ++i) {
		getline(cin, s);
		if (s.find("easy") != s.npos || s.find("qiandao") != s.npos) continue;
		if (!m) {
			cout << s << endl;
		}
		m--;
	}
	if (m >= 0) {
		cout << "Wo AK le" << endl;
	}
	return 0;
} 

1-7

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

const int N = 2e4 + 7;
const int M = 1e6 + 7;

int n, m, k;
int a[N];
int num[M];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	cin >> n;
	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
		num[ a[i] ]++; 
	}
	sort(a + 1, a + 1 + n);
	cout << a[1] << " " << num[ a[1] ] << endl;
	cout << a[n] << " " << num[ a[n] ] << endl;
	return 0;
} 

1-8

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

const int N = 2e4 + 7;
const int M = 1e6 + 7;

int n, m, k;
int a[N];
int b[N];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	cin >> a[1] >> a[2] >> n;
	int i = 1;
	int tot = 2;
	while (tot <= n) {
		int tmp = a[i] * a[i + 1];
		int len = 0;
		do {
			b[len++] = tmp % 10;
			tmp /= 10;
		}while (tmp);
		while (len--) {
			a[++tot] = b[len];
		}
		i++;
	}
	for (int i = 1; i <= n; ++i) {
		cout << a[i] << " \n"[i == n];
	}
	return 0;
} 

2-1

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

const int N = 2e4 + 7;
const int M = 1e6 + 7;

int n, m, k, op;
int a[N];
int b[N];
string s[N];
stack<char> sta;
int tot, last[N];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(1);
	cin >> n >> m >> k;
	for (int i = 1; i <= n; ++i) {
		cin >> s[i];
	}
	while (cin >> op, op != -1) {
		if (op == 0) {
			if (!sta.empty()) {
				cout << sta.top();
				sta.pop();
			}
			continue;
		}
		if (last[op] < m) {
			if (sta.size() == k) {
				cout << sta.top();
				sta.pop();
			}
			sta.push(s[op][last[op]++]);
		}
	}
	return 0;
} 

2-2

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e4 + 7;

int n, m, k;
int in[N], head[N];
int path[N], ans[N];
int maxLen, tot;

void work(int len) {
	for (int i = 1; i <= len; ++i) {
		ans[i] = path[i];
	}
	maxLen = len;
}

bool cmp(int len) {
	for (int i = 1; i <= len; ++i) {
		if (ans[i] > path[i]) return true;
		if (ans[i] < path[i]) return false;
	}
	return false;
}

struct Edge {
	int nxt, v;
	
	Edge () {}
	Edge (int nxt, int v) : nxt(nxt), v(v) {}
}edge[N];

void addedge(int u, int v) {
	edge[tot] = Edge(head[u], v);
	head[u] = tot++;
}

void dfs(int u, int len) {
	path[len] = u;
	if (head[u] == -1) {
		if (len > maxLen) work(len);
		else if (len == maxLen && cmp(len)) work(len);
	}
	for (int i = head[u]; ~i; i = edge[i].nxt) {
		int v = edge[i].v;
		dfs(v, len + 1);
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> m;
		head[i] = -1;
		path[i] = -1;
		while (m--) {
			cin >> k;
			addedge(i, k);
			in[k]++;
		}
	}
	for (int i = 0; i < n; ++i) {
		if (!in[i]) {
			dfs(i, 1);
			break;
		}
	}
	cout << maxLen << endl;
	for (int i = 1; i <= maxLen; ++i) {
		cout << ans[i] << " \n"[i == maxLen];
	}
	return 0;
}

2-3

vector竟然能直接比大小,打个天梯赛学到许多Orz

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e4 + 7;

int n, m, k;
vector< vector<int> >v[N];
map< vector<int>, int >num;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m;
	
	for (int i = 0; i < n; ++i) {
		vector<int> G(m);
		for (int j = 0; j < m; ++j) {
			cin >> G[j];
		}
		num[G]++;
	}
	int ans = 0;
	for (auto t : num) {
		v[t.second].push_back(t.first);
		ans++;
	}
	cout << ans << endl;
	for (int i = n; i >= 1; --i) {
		for (auto t : v[i]) {
			cout << i;
			for (auto a : t) {
				cout << " " << a;
			}
			cout << endl;
		}
	}
	return 0;
}

2-4

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e5 + 7;

int n, m, k, op, id;
int sav[N];
vector<int> G[N];

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n >> m;
	for (int i = 1, t; i <= n; ++i) {
		cin >> k;
		while (k--) {
			cin >> t;
			G[i].push_back(t);
		}
	}
	int now = 1;
	while (m--) {
		cin >> op >> id;
		if (op == 0) {
			now = G[now][id - 1];
		}
		if (op == 1) {
			sav[id] = now;
			cout << now << endl;
		}
		if (op == 2) {
			now = sav[id];
		}
	}
	cout << now << endl;
	return 0;
}

3-1

发现求出距离之后每次答案都是能直接更新的。为了在所有点中找出最优的点,要用线段树维护一下。注意一下不能到的点。

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

typedef long long ll;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

int n, m, q;
int head[2][N], tot[2];
ll dis[N], disR[N];
ll a[N];
ll money[N];

struct Edge {
	int nxt, v;
	ll w;
	
	Edge () {}
	Edge (int nxt, int v, ll w) : nxt(nxt), v(v), w(w) {}
}edge[2][N << 1];

struct qnode {
	int u;
	ll w;
	
	qnode () {}
	qnode (int u, ll w) : u(u), w(w) {}
	
	bool operator < (const qnode &a) const {
		return w > a.w;
	}
};

void addedge(int u, int v, ll w, int type) {
	edge[type][ tot[type] ] = Edge(head[type][u], v, w);
	head[type][u] = tot[type]++;
}

void Dijkstra(int s, int type, ll dis[]) {
	for (int i = 1; i <= n; ++i) {
		dis[i] = INF;
	}
	dis[s] = 0;
	priority_queue<qnode> q;
	q.push(qnode(s, 0));
	while (!q.empty()) {
		int u = q.top().u;
		q.pop();
		for (int i = head[type][u]; ~i; i = edge[type][i].nxt) {
			int v = edge[type][i].v;
			ll w = edge[type][i].w;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				q.push(qnode(v, dis[v]));
			}
		}
	}
}

struct Seg {
	ll t[N << 2];
	
	void up(int id) {
		t[id] = min(t[id << 1], t[id << 1 | 1]);
	}
	
	void build(int id, int l, int r) {
		t[id] = 0;
		if (l == r) {
			t[id] = dis[l] + (disR[l] + money[l] - 1) / money[l];
			if (dis[l] == INF || disR[l] == INF) t[id] = INF;
			return;
		}
		int mid = l + r >> 1;
		build(id << 1, l, mid);
		build(id << 1 | 1, mid + 1, r);
		up(id);
	}
	
	void modify(int id, int l, int r, int pos, ll v) {
		if (l == r) {
			t[id] = dis[l] + (disR[l] + v - 1) / v;
			if (dis[l] == INF || disR[l] == INF) t[id] = INF;
			return;
		}
		int mid = l + r >> 1;
		if (pos <= mid) modify(id << 1, l, mid, pos, v);
		else modify(id << 1 | 1, mid + 1, r, pos, v);
		up(id);
	}
	
	ll query() {
		return t[1];
	}
}seg;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	memset(head, -1, sizeof(head));
	cin >> n >> m >> q;
	for (int i = 1, u, v, c, d; i <= m; ++i) {
		cin >> u >> v >> c >> d;
		addedge(u, v, c, 0);
		addedge(v, u, d, 1);
	}
	for (int i = 1; i <= n; ++i) {
		cin >> money[i];
	}
	Dijkstra(1, 0, dis);
	Dijkstra(n, 1, disR);
	seg.build(1, 1, n);
	for (int i = 1, x, y; i <= q; ++i) {
		cin >> x >> y;
		seg.modify(1, 1, n, x, y);
		cout << seg.query() << endl;	
	}
	return 0;
}

3-2

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

typedef long long ll;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

int n, m, k;
int p[N], ans[N];
vector<int> G[107], h[107];
bool vis[N];

bool check(int id, int pos) {
    for (auto v : h[id]) {
        if (v != p[pos]) return false;
        pos++;
    }
    return true;
}

bool dfs(int id, int now) {
    if (id >= n) return true;
    for (auto v : G[ p[id] ]) {
        if (vis[v]) continue;
        if (check(v, id)) {
            vis[v] = 1;
            ans[now] = v;
            if (dfs(id + h[v].size() - 1, now + 1)) return true;
            vis[v] = 0;
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> p[i];
    }
    cin >> m;
    for (int i = 1, t; i <= m; ++i) {
        cin >> k;
        for (int j = 1; j <= k; ++j) {
            cin >> t;
            h[i].push_back(t);
            if (j == 1) G[t].push_back(i);
        }
    }
    dfs(1, 1);
    for (int i = 1; i <= m; ++i) {
        cout << ans[i] << " \n"[i == m];
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值