The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)

The 2014 ACM-ICPC Asia Mudanjiang Regional Contest

题目链接

没去现场。做的网络同步赛。感觉还能够,搞了6题

A:这是签到题,对于A堆除掉。假设没剩余在减一。B堆直接除掉 + 1就能够了

B:二分贪心,二分长度。然后会发现本质上是在树上最长链上找两点,那么有二分出来的长度了,就从两端分别往里移动那么长,那两个位置就是放置位置。然后在推断一下就能够了

D:概率DP。首先知道放一个棋子。能够等价移动到右上角区域,那么就能够dp[x][y][k],表示已经完毕x行y列。已经放了k个棋子,那么棋盘被划分成4个区域。利用这个区域能够算概率,然后去转移就可以

H:字符串处理,先hash掉,记录每一个hash值相应的l,r区间。离线处理完每次询问输出就能够了,注意细节

I:签到题,注意0的时候是等于0就能够了

K:贪心,假设数字个数不够。在前面补是最优的。然后从左往右扫描一遍,每次遇到1个星号要扣掉两个数字,假设没有,这须要交换操作。交换肯定和最后面的数字交换是最优的,最后还要考虑一种特殊情况。就是没有交换,而且最后还有数字,这时候要加入一个星号

代码:

A:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 55;
int t, n, m;

int a, b, suma, sumb;

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		suma = sumb = 0;
		for (int i = 0; i < n - 1; i++) {
			scanf("%d", &a);
			suma += a;
		}
		for (int i = 0; i < m; i++) {
			scanf("%d", &b);
			sumb += b;
		}
		int l, r;
		l = suma / (n - 1) - (suma % (n - 1) == 0);
		r = sumb / m + 1;
		if (l > r) swap(l, r);
		printf("%d %d\n", l, r);
	}
	return 0;
}

B:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

const int N = 200005;

struct Edge {
	int u, v;
	Edge() {}
	Edge(int u, int v) {
		this->u = u;
		this->v = v;
	}
} E[N * 2];

int first[N], next[N * 2], en;

void add_Edge(int u, int v) {
	E[en] = Edge(u, v);
	next[en] = first[u];
	first[u] = en++;
}

const int INF = 0x3f3f3f3f;
int t, n, vis[N], f[N], u1, u2, Q[N * 2];

int bfs(int root) {
	int head = 0, rear = 0;
	vis[root] = 0;
	Q[rear++] = root;
	f[root] = 0;
	int u;
	while (head < rear) {
		u = Q[head++];
		for (int i = first[u]; i + 1; i = next[i]) {
			Edge e = E[i];
			int v = e.v;
			if (vis[v] > vis[u] + 1) {
				vis[v] = vis[u] + 1;
				f[v] = u;
				Q[rear++] = v;
			}
		}
	}
	return u;
}

bool judge(int len) {
	memset(vis, INF, sizeof(vis));
	u1 = bfs(1);
	for (int i = 0; i < len; i++) {
		if (f[u1] == 0) {
			u2 = u1 % n + 1;
			return true;
		}
		u1 = f[u1];
	}
	memset(vis, INF, sizeof(vis));
	u2 = bfs(u1);
	for (int i = 0; i < len; i++) {
		if (f[u2] == 0) return true;
		u2 = f[u2];
	}
	bfs(u2);
	for (int i = 1; i <= n; i++)
		if (vis[i] > len) return false;
	return true;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		en = 0;
		memset(first, -1, sizeof(first));
		scanf("%d", &n);
		int u, v;
		for (int i = 1; i < n; i++) {
			scanf("%d%d", &u, &v);
			add_Edge(u, v);
			add_Edge(v, u);
		}
		if (n == 2) {
			printf("0 1 2\n");
			continue;
		}
		int l = 0, r = n;
		while (l < r) {
			int mid = (l + r) / 2;
			if (judge(mid)) r = mid;
			else l = mid + 1;
		}
		judge(l);
		if (u1 == u2) u2 = u2 % n + 1;
		printf("%d %d %d\n", l, u1, u2);
	}
	return 0;
}


D:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 55;
int t, n, m;
double dp[N][N][N * N];

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		memset(dp, 0, sizeof(dp));
		dp[0][0][0] = 1;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				for (int k = max(i, j); k <= i * j; k++) {
					double p1 = (i * j - (k - 1)) * 1.0;
					double p2 = (n - i + 1) * j;
					double p3 = i * (m - j + 1);
					double p4 = (n - i + 1) * (m - j + 1);
					dp[i][j][k] = dp[i][j][k - 1] * p1 + dp[i - 1][j][k - 1] * p2 + dp[i][j - 1][k - 1] * p3 + dp[i - 1][j - 1][k - 1] * p4;
					dp[i][j][k] /= (n * m - (k - 1));
				}
			}
		}
		double ans = 0;
		for (int i = max(n, m); i <= n * m; i++)
			ans += dp[n][m][i] * i - dp[n][m][i - 1] * i;
		printf("%.12lf\n", ans);
	}
	return 0;
}

H:

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

#define MP(a,b) make_pair(a,b)

typedef unsigned long long ull;
const ull x = 123;
const int N = 200005;
typedef pair<int, int> pii;

char str[N], q[N];
map<ull, pii> g;

int t, u, k, lens;

int build(ull st) {
	int flag = 1;
	while (u < lens) {
		if (str[u] == '{') {
			flag = 0;
			u++;
		}
		if (str[u] == '}') {
			u++;
			return u;
		}
		ull nt = st;
		while (str[u] != ':' && str[u] != ',' && str[u] != '}')
			nt = nt * x + str[u++];
		if (str[u] == ':') {
			int l = ++u;
			int r = build(nt * x + '.');
			g[nt] = MP(l, r);
		}
		if (str[u] == '}') {
			if (!flag)
				u++;
			return u;
		}
		if (str[u] == ',') {
			if (flag) return u;
			u++;
		}
	}
}

int main() {
	scanf("%d", &t);
	while (t--) {
		u = 0;
		g.clear();
		scanf("%s", str);
		lens = strlen(str);
		build(0);
		scanf("%d", &k);
		while (k--) {
			scanf("%s", q);
			ull tmp = 0;
			int len = strlen(q);
			for (int i = 0; i < len; i++)
				tmp = tmp * x + q[i];
			if (!g.count(tmp)) {
				printf("Error!\n");
				continue;
			}
			int l = g[tmp].first, r = g[tmp].second;
			for (int i = l; i < r; i++)
				printf("%c", str[i]);
			printf("\n");
		}
	}
	return 0;
}

I:

#include <cstdio>
#include <cstring>
#include <cmath>

int t, n;
char str[10];

double solve(int x) {
	if (x == 0) return 0;
	double sb = x * 1.0 / 100;
	if (str[0] == 'b') return sb * log2(sb);
	if (str[0] == 'n') return sb * log(sb);
	if (str[0] == 'd') return sb * log10(sb);
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d%s", &n, str);
		double ans = 0;
		int x;
		for (int i = 0; i < n; i++) {
			scanf("%d", &x);
			ans += solve(x);
		}
		printf("%.12lf\n", -ans);
	}
	return 0;
}

K:

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

#define MP(a,b) make_pair(a,b)

typedef unsigned long long ull;
const ull x = 123;
const int N = 200005;
typedef pair<int, int> pii;

char str[N], q[N];
map<ull, pii> g;

int t, u, k, lens;

int build(ull st) {
	int flag = 1;
	while (u < lens) {
		if (str[u] == '{') {
			flag = 0;
			u++;
		}
		if (str[u] == '}') {
			u++;
			return u;
		}
		ull nt = st;
		while (str[u] != ':' && str[u] != ',' && str[u] != '}')
			nt = nt * x + str[u++];
		if (str[u] == ':') {
			int l = ++u;
			int r = build(nt * x + '.');
			g[nt] = MP(l, r);
		}
		if (str[u] == '}') {
			if (!flag)
				u++;
			return u;
		}
		if (str[u] == ',') {
			if (flag) return u;
			u++;
		}
	}
}

int main() {
	scanf("%d", &t);
	while (t--) {
		u = 0;
		g.clear();
		scanf("%s", str);
		lens = strlen(str);
		build(0);
		scanf("%d", &k);
		while (k--) {
			scanf("%s", q);
			ull tmp = 0;
			int len = strlen(q);
			for (int i = 0; i < len; i++)
				tmp = tmp * x + q[i];
			if (!g.count(tmp)) {
				printf("Error!\n");
				continue;
			}
			int l = g[tmp].first, r = g[tmp].second;
			for (int i = l; i < r; i++)
				printf("%c", str[i]);
			printf("\n");
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM-ICPC(国际大学生程序设计竞)是一项面向大学生的计算机编程竞,涉及算法和数据结构等领域。在比中,选手需要解决一系列编程问题,使用合适的算法和数据结构来实现正确和高效的解决方案。 对于整理ACM-ICPC模板,以下是一些建议: 1. 了解比要求:首先,你需要了解ACM-ICPC的具体要求和规则。这包括了解比所涉及的算法和数据结构,以及题目的类型和难度等。 2. 收集资料:收集与ACM-ICPC相关的资料,包括经典算法和数据结构的实现代码、常见问题的解题思路等。可以参考教材、博客、论文等资源。 3. 整理模板:将收集到的资料整理成模板。可以按照算法和数据结构的分类进行整理,例如排序算法、图算法、字符串算法等。对每个模板,添加必要的注释和示例代码,以便理解和使用。 4. 测试代码:对每个模板编写测试代码,确保它们的正确性和可靠性。可以使用已知的测试用例或自行设计测试用例。 5. 更新与扩充:定期更新和扩充模板,以适应ACM-ICPC中新出现的算法和数据结构。同时,根据自己的经验和理解,对模板进行优化和改进。 6. 练习和复习:在比之前,利用整理好的模板进行练习和复习。尝试解决一些经典问题,使用模板中的算法和数据结构进行实现,并进行优化。 希望这些建议对你整理ACM-ICPC模板有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值