AtCoder Beginner Contest 193

A Discount

int main()
{
	IOS;
	int a, b;
	cin >> a >> b;
	cout << setprecision(10) << (double)(a - b) / a * 100 << endl;
	return 0;
}

B Play Snuke

int main()
{
	int n;
	scanf("%d", &n);
	int res = INF;
	for(int i = 1; i <= n; ++ i)
	{
		int a, p, x; scanf("%d%d%d", &a, &p, &x);
		if(a < x) res = min(p, res);
	}
	if(res < INF) printf("%d
", res);
	else puts("-1");
	return 0;
}

C

(a) 只需要枚举到 (sqrt(n)), 用 set 判重即可

int main()
{
	IOS;
	LL n; cin >> n;
	unordered_set<LL> s;
	for(LL i = 2; i <= n / i; ++ i)
	{
		LL t = i * i;
		while(t <= n) { s.insert(t); t *= i; }
	}
	cout << n - s.size() << endl;
	return 0;
}

D Poker

枚举最后一位,判断该放置方法是否合法, 此方法的方案数为 (v[i] * (v[j] - (i == j)))
总方案数为 ((9 * k - 8) * (9 * k - 9))

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

LL score(string s)
{
	vector<LL> v(10);
	iota(v.begin(), v.end(), 0);
	for(auto c : s)
		v[(int)(c - '0')] *= 10;
	return accumulate(v.begin(), v.end(), 0);
}

int main()
{
	IOS;
	LL k;
	string a, b;
	cin >> k >> a >> b;
	vector<LL> v(10, k);
	for(auto c : a + b) v[(int)(c - '0')] --;
	LL res = 0;
	for(LL i = 1; i <= 9; ++ i)
		for(LL j = 1; j <= 9; ++ j)
		{
			a.back() = '0' + i;
			b.back() = '0' + j;
			if(score(a) <= score(b)) continue;
			else res += v[i] * (v[j] - (i == j));
		}
	cout << setprecision(10) << (double)res / (9 * k - 8) / (9 * k - 9) << endl;
	return 0;
}

E Oversleeping

求满足 (X le t ; mod (2X + 2Y) < X + Y)(P le t ; mod (P + Q) < P + Q) 的最小正整数 (t)
(Y)(Q) 都比较小,可以直接枚举
问题转化成 (egin{cases}t equiv m_1 (mod;a_1)\t equiv m_2(mod;a_2)end{cases}), 用扩展中国剩余定理求解即可.

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)

using namespace std;

typedef long long LL;

LL exgcd(LL a, LL b, LL &x, LL &y)
{
	if(!b)
	{
		x = 1, y = 0;
		return a;
	}
	LL d = exgcd(b, a % b, y, x);
	y -= a / b * x;
	return d;
}

int main()
{
	IOS;
	LL X, Y, P, Q;
	int __;
	cin >> __;
	while(__ -- )
	{
		cin >> X >> Y >> P >> Q;
		LL res = 2e18;
		for(int i = 0; i < Y; ++ i)
			for(int j = 0; j < Q; ++ j)
			{
				LL a1 = 2 * X + 2 * Y, a2 = P + Q;
				LL m1 = X + i, m2 = P + j;
				LL k1, k2;
				LL d = exgcd(a1, a2, k1, k2);
				if((m2 - m1) % d) continue;
				k1 *= (m2 - m1) / d;
				LL t = a2 / d;
				k1 = (k1 % t + t) % t;
				m1 = a1 * k1 + m1;
				a1 = abs(a1 / d * a2);
				res = min(res, (m1 % a1 + a1) % a1);
			}
		if(res < 2e18) cout << res << endl;
		else cout << "infinity" << endl;
	}
	return 0;
}

F Zebraness

(i + j) 为偶数的格子和为奇数的格子形成一张二分图,考虑将 (i + j) 为奇数的格子上的颜色翻转,同色的块在翻转后变成异色,则会对答案产生贡献,那么最小化这个贡献,用总边数减掉这些反的贡献,就是在原图中贡献的最大值。

  • 从虚拟源点向新图上为白色的点连一条容量为 (+infty) 的边,确保这条边不会被选成割边
  • 从新图上为黑色的点向虚拟汇点连一条容量为 (+infty) 的边,确保这条边不会被选成割边
  • 相邻的点之间连正反两条容量为 (1) 的边,这些边可以被选作割边

答案即为 (2 * n * (n - 1)) - 最小割

#include <bits/stdc++.h>
using namespace std;

const int N = 10000 + 10;
const int M = (10000 + 100 * 100 * 4 + 10) * 2;
const int INF = 1e9;

int n, S, T;
struct Edge
{
	int to, nxt, flow;
}line[M];
int fist[N], idx;
int d[N], cur[N];
char str[110];

int get(int x, int y)
{
	return n * (x - 1) + y; 
}

void add(int x, int y, int z1, int z2)
{
	line[idx] = {y, fist[x], z1};
	fist[x] = idx ++;
	line[idx] = {x, fist[y], z2};
	fist[y] = idx ++;
}

bool bfs()
{
	queue<int> q;
	memset(d, -1, sizeof d);
	q.push(S), d[S] = 0, cur[S] = fist[S];
	while(!q.empty())
	{
		int u = q.front(); q.pop();
		for(int i = fist[u]; ~i; i = line[i].nxt)
		{
			int v = line[i].to;
			if(d[v] == -1 && line[i].flow)
			{
				d[v] = d[u] + 1;
				cur[v] = fist[v];
				if(v == T) return 1;
				q.push(v);
			}
		}
	}
	return 0;
}

int find(int u, int limit)
{
	if(u == T) return limit;
	int flow = 0;
	for(int i = cur[u]; i != -1 && flow < limit; i = line[i].nxt)
	{
		cur[u] = i;
		int v = line[i].to;
		if(d[v] == d[u] + 1 && line[i].flow)
		{
			int t = find(v, min(line[i].flow, limit - flow));
			if(!t) d[v] = -1;
			line[i].flow -= t;
			line[i ^ 1].flow += t;
			flow += t;
		}
	}
	return flow;
}

int dinic()
{
	int res = 0, flow;
	while(bfs()) while(flow = find(S, INF)) res += flow;
	return res;
}

int main()
{
	scanf("%d", &n);
	memset(fist, -1, sizeof fist);
	S = 0, T = n * n + 1;

	for(int i = 1; i <= n; ++ i)
	{
		scanf("%s", str + 1);
		for(int j = 1; j <= n; ++ j)
		{
			if(str[j] == '?') continue;
			if((i + j) & 1) str[j] = (str[j] == 'B') ? 'W' : 'B';
			if(str[j] == 'W') add(S, get(i, j), INF, 0);
			if(str[j] == 'B') add(get(i, j), T, INF, 0);
		}
	}
	for(int i = 1; i <= n; ++ i)
		for(int j = 1; j <= n; ++ j)
		{
			if(j + 1 <= n) add(get(i, j), get(i, j + 1), 1, 1);
			if(i + 1 <= n) add(get(i, j), get(i + 1, j), 1, 1);
		}
	printf("%d
", 2 * n * (n - 1) - dinic());
	return 0;
}
原文地址:https://www.cnblogs.com/ooctober/p/14495485.html