2020 HDU Multi-University Training Contest 4(部分)

6803 Blow up the Enemy

难得一见的比赛水题

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn = 1000 + 5;
int T, n, A[maxn], D[maxn];
int main(void) {
	scanf("%d", &T);
	while (T--){
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
			scanf("%d%d", &A[i], &D[i]);
		double p = 0, s[maxn] = { 0 };
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++) {
				if (A[i] >= 100 && A[j] >= 100) { s[j] += 0.5; continue; }
				int t1 = (int)(ceil((100.0 - A[i]) / A[i])) * D[i];
				int t2 = (int)(ceil((100.0 - A[j]) / A[j])) * D[j];
				if (t1 == t2)s[j] += 0.5;
				if (t1 > t2) s[j] += 1;
				if (t1 < t2) s[j] += 0;
			}
		p = s[1];
		for (int i = 2; i <= n; i++)
			if (p < s[i])p = s[i];
		printf("%f\n", p / n);
	}
	return 0;
}

6805 Deliver the Cake

可以说应该算是个简单题吧,就是在longlong这里捣鼓了好一会儿。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const ll inf = 1e16;
const int N = 4e5 + 5;
int T, n, m, s, t;
int u, v, vis[N][2];
ll w, x, dis[N][2];
char str[N];
struct node {
	int to;
	ll w;
	node() {}
	node(int to, ll w) :to(to), w(w) {}
};
struct state {
	int id, hand;
	ll dis;
	state() {}
	state(int id, int hand, ll dis) :id(id), hand(hand), dis(dis) {}
	bool operator < (const state& B) const { return dis > B.dis; }
}p;
vector<node>e[N];
int main(void) {
	scanf("%d", &T);
	while (T--) {
		scanf("%d %d %d %d %lld", &n, &m, &s, &t, &x);
		scanf("%s", str + 1);
		for (int i = 1; i <= n; i++) {
			vis[i][0] = vis[i][1] = 0;
			dis[i][0] = dis[i][1] = inf;
			if (str[i] == 'L')vis[i][1] = 1;
			if (str[i] == 'R')vis[i][0] = 1;
			e[i].clear();
		}
		for (int i = 0; i < m; i++) {
			scanf("%d %d %lld", &u, &v, &w);
			e[u].push_back(node(v, w));
			e[v].push_back(node(u, w));
		}
		priority_queue<state>pq;
		if (str[s] == 'L')pq.push(state(s, 0, 0));
		if (str[s] == 'R')pq.push(state(s, 1, 0));
		if (str[s] == 'M') {
			pq.push(state(s, 0, 0));
			pq.push(state(s, 1, 0));
		}
		dis[s][0] = dis[s][1] = 0;
		while (!pq.empty()){
			state u = pq.top(); pq.pop();
			vis[u.id][u.hand] = 1;
			if (vis[t][0] && vis[t][1])break;
			for (int i = 0; i < e[u.id].size(); i++) {
				int v = e[u.id][i].to;
				ll w = e[u.id][i].w;
				if (str[v] == 'L') {
					if (vis[v][0])continue;
					if (u.hand == 1)w += x;
					if (dis[v][0] > u.dis + w) {
						dis[v][0] = u.dis + w;
						pq.push(state(v, 0, dis[v][0]));
					}
				}
				else if (str[v] == 'R') {
					if (vis[v][1])continue;
					if (u.hand == 0)w += x;
					if (dis[v][1] > u.dis + w) {
						dis[v][1] = u.dis + w;
						pq.push(state(v, 1, dis[v][1]));
					}
				}
				else {
					if (!vis[v][0]) {
						if (u.hand == 1)w += x;
						if (dis[v][0] > u.dis + w) {
							dis[v][0] = u.dis + w;
							pq.push(state(v, 0, dis[v][0]));
						}
					}
					w = e[u.id][i].w;
					if (!vis[v][1]) {
						if (u.hand == 0)w += x;
						if (dis[v][1] > u.dis + w) {
							dis[v][1] = u.dis + w;
							pq.push(state(v, 1, dis[v][1]));
						}
					}
				}
			}
		}
		printf("%lld\n", min(dis[t][0], dis[t][1]));
	}
	return 0;
}

6806 Equal Sentences

基础DP

#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const ll mod = 1e9 + 7;
int T, n, cnt, a[maxn];
ll dp[maxn][2];
string tmp;
map<string, int>id;
int main(void) {
    scanf("%d", &T);
    while (T--){
        cnt = 0;
        scanf("%d", &n);
        id.clear();
        for (int i = 1; i <= n; i++) {
            cin >> tmp;
            if (!id.count(tmp))id[tmp] = ++cnt;
            a[i] = id[tmp];
            dp[i][0] = dp[i][1] = 0;
        }
        dp[1][0] = 1, dp[1][1] = 0;
        for (int i = 2; i <= n; i++) {
            dp[i][0] = dp[i - 1][1] + dp[i - 1][0] % mod;
            if (a[i] != a[i - 1])dp[i][1] = dp[i - 1][0] % mod;
            else dp[i][1] = 0;
        }
        printf("%lld\n", (dp[n][1] + dp[n][0]) % mod);
    }
    return 0;
}

6808 Go Running

Dinic算法求二分图最大匹配

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
struct node {
	int to, cap, next;
};
const int maxn = 2e6 + 10;
node e[maxn];
int n, m, start, tend;
int head[maxn];//链式向前星
int cur[maxn];
int depth[maxn];//dinic分层
int cnt, T;
int Q[maxn << 1];

bool bfs() {
	memset(depth, -1, sizeof(depth));
	memcpy(cur, head, sizeof(cur));
	int Thead = 0, Ttail = 0;
	Q[Ttail++] = start;
	depth[start] = 0;
	while (Thead < Ttail) {
		int u = Q[Thead];
		if (u == tend)return true;
		for (int i = head[u]; i != -1; i = e[i].next) {
			int v = e[i].to;
			if (depth[v] == -1 && e[i].cap > 0) {
				//没有分配层数且仍有容量
				depth[v] = depth[u] + 1;
				Q[Ttail++] = v;
			}
		}
		Thead++;
	}
	return false;
}
int dfs(int u, int cap) {
	if (u == tend)return cap;
	int flow = 0, f;
	for (int& i = cur[u]; i != -1; i = e[i].next) {
		if ((depth[u] + 1 == depth[e[i].to]) && e[i].cap > 0) {
			int f = dfs(e[i].to, min(cap - flow, e[i].cap));
			if (f > 0) {
				e[i].cap -= f;
				e[i ^ 1].cap += f;
				flow += f;
				if (flow == cap)break;
			}
		}
	}
	if (!flow)depth[u] = -2;//防止重搜
	return flow;
}

void addedge(int u, int v, int w) {
	e[cnt].to = v;//u指向的端点
	e[cnt].cap = w;//权值
	e[cnt].next = head[u];//指向上一条边
	head[u] = cnt++;//指向以u为端点的最新一条边
}

int X[maxn], Y[maxn];
int a[maxn], b[maxn];

int main(void) {
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	scanf("%d", &T);
	while (T--){
		scanf("%d", &n);
		memset(head, -1, sizeof(head));
		cnt = 0;
		for (int i = 0; i < n; i++) {
			int t, x;
			scanf("%d%d", &t, &x);
			X[i] = x + t; a[i] = X[i];
			Y[i] = x - t; b[i] = Y[i];
		}
		sort(a, a + n);
		int cnta = unique(a, a + n) - a;
		sort(b, b + n);
		int cntb = unique(b, b + n) - b;
		start = cnta + cntb + 5; tend = start + 1;
		for (int i = 0; i < n; i++) {//离散化
			int pos1 = lower_bound(a, a + cnta, X[i]) - a;
			int pos2 = lower_bound(b, b + cntb, Y[i]) - b + cnta + 2;
			addedge(pos1, pos2, 1);
			addedge(pos2, pos1, 0);
		}
		for (int i = 0; i < cnta; i++) {
			addedge(start, i, 1);
			addedge(i, start, 0);
		}
		for (int i = 0; i < cntb; i++) {
			addedge(i + cnta + 2, tend, 1);
			addedge(tend, i + cnta + 2, 0);
		}
		int ans = 0;
		while (bfs()){//Dinic算法
			ans += dfs(start, inf);
		}
		printf("%d\n", ans);
	}
	return 0;
}

6812 Kindergarten Physics

考虑到数据范围,最坏情况a=100,b=100,t0=100距离移动也不超过10^-6,因此直接输出d即可。

#include<cstdio>
using namespace std;
int T;
double a, b, d, t0;
int main(void) {
	scanf("%d", &T);
	while (T--){
		scanf("%lf%lf%lf%lf", &a, &b, &d, &t0);
		printf("%f\n", d);
	}
	return 0;
}

6813 Last Problem

构造题,但是要注意paint的顺序,(n-1)和(n-4)的必须在一条线上,(n-2)和(n-3)在一条线上。
否则可能不合规则,如n=6,在上面n-1,右边n-2,下面n-3,左边n-4的顺序下,在paint右边为4时,4还要继续向右边piant 2,但是此时已经有2在左边了(6要paint的位置上面为5,5的下面是5-3=2)。

#include<cstdio>
#include<cstring>
using namespace std;
int n, dp[205][205];
void paint(int x, int y, int c) {
    if (c <= 0)return;
    if (dp[x][y + 1] != c - 1)paint(x, y + 1, c - 1);
    if (dp[x + 1][y] != c - 2)paint(x + 1, y, c - 2);
    if (dp[x - 1][y] != c - 3)paint(x - 1, y, c - 3);
    if (dp[x][y - 1] != c - 4)paint(x, y - 1, c - 4);
    dp[x][y] = c;
    printf("%d %d %d\n", x, y, c);
}
int main(void) {
    scanf("%d", &n);
    paint(101, 101, n);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JILIN.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值