AtCoder Beginner Contest 192

A Star

#include <cstdio>
using namespace std;

int n;

int main()
{
	scanf("%d", &n);
	printf("%d
", 100 - n % 100);
	return 0;
}

B uNrEaDaBlE sTrInG

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

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

string str;

bool check()
{
	for(int i = 0; i < (int)str.size(); ++ i)
		if(i % 2 && islower(str[i])) return 0;
		else if(i % 2 == 0 && isupper(str[i])) return 0;
	return 1;
}

int main()
{
	IOS;
	cin >> str;
	if(check()) puts("Yes");
	else puts("No");
	return 0;
}

C Kaprekar Number

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

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

LL n, k;

LL f(LL x)
{
	vector<int> g1, g2;
	while(x) g1.push_back(x % 10), g2.push_back(x % 10), x /= 10;
	sort(g1.begin(), g1.end(), greater<int>());
	sort(g2.begin(), g2.end());
	LL res = 0;
	for(int i = 0; i < (int)g1.size(); ++ i)
		res = res * 10 + g1[i] - g2[i];
	return res;
}

int main()
{
	IOS;
	cin >> n >> k;
	LL a0 = n;
	for(int i = 1; i <= k; ++ i) a0 = f(a0);
	cout << a0 << endl;
	return 0;
}

D Base n

特判 (X) 只有一位的情况,无论基底是几,得到的数都是原数,判断原数和 (M) 的大小关系即可
对于其他情况,当基底越大,得到的值也就越大,具有单调性,可以二分基底
计算以 (mid) 为基底的数与 (M) 的大小关系时,直接计算答案会爆 (long ; long), 注意在过程中判断

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

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

LL m;
string s;

int find()
{
	int res = 0;
	for(auto x : s) res = max(res, x - '0');	
	return res;
}

bool check(LL mid)
{
	LL res = 0;
	for(auto x : s) 
	{
		if(res > m / mid) return 0;
		res = res * mid + x - '0';
		if(res > m) return 0;
	}
	return 1;
}

int main()
{
	IOS;
	cin >> s >> m;
	int d = find();
	if(s.size() == 1) 
	{
		if((LL)d <= m) cout << "1" << endl;
		else cout << "0" << endl;
		return 0;
	}
	LL l = d + 1, res = 0, r = m;
	while(l <= r)
	{
		LL mid = (l + r) >> 1;
		if(check(mid))
		{
			res = mid;
			l = mid + 1;
		}
		else r = mid - 1;
	}
	if(res) cout << res - d << endl;
	else cout << "0" << endl;
	return 0;
}

E Train

(u) 到达 (v) 的时间为 (leftlceil dfrac{d[u]}{K_i} ight ceil * K_i + T_i), 建双向边跑 (dijkstra) 即可

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

typedef long long LL;
const int M = 2e5 + 10;
const int N = 1e5 + 10;
const LL INF = 1e18;

int n, m, S, T;
LL d[N]; 
struct Edge
{
	int to, nxt, T, K;
}line[M];
int fist[N], idx;
bool st[N];
struct zt
{
	int from;
	LL d;
};

bool operator < (zt a, zt b)
{
	return a.d > b.d;
}

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

void heap_dijkstra()
{
	for(int i = 1; i <= n; ++ i) d[i] = INF;
	priority_queue<zt> q;
	q.push({S, 0}), d[S] = 0;
	while(!q.empty())
	{
		zt u = q.top(); q.pop();
		if(st[u.from]) continue;
		st[u.from] = 1;
		for(int i = fist[u.from]; ~i; i = line[i].nxt)
		{
			int v = line[i].to;
			LL tim = (d[u.from] + line[i].K - 1) / line[i].K * line[i].K + line[i].T;
			if(d[v] > tim)
			{
				d[v] = tim;
				q.push({v, d[v]});
			}
		}
	}
}

int main()
{
	scanf("%d%d%d%d", &n, &m, &S, &T);
	memset(fist, -1, sizeof fist);
	for(int i = 1; i <= m; ++ i)
	{
		int a, b, c, d;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		add(a, b, c, d);
		add(b, a, c, d);
	}
	heap_dijkstra();
	if(d[T] < INF) printf("%lld
", d[T]);
	else puts("-1");
	return 0;
}

F Potion

(sum A_i) 为从 (n) 个元素中选出 (p) 个元素的权值和
目标是使在满足(p | (X - sum A_i)) 条件下最小化 (dfrac{X - sum A_i}{p})
故对于每个 (p) ,求出在 (sum A_i) mod (p) == (X) mod (p) 的条件下 (sum A_i) 的最大值即可
问题转化为求 (i) 个数中取出 (j) 个且和的余数为 (k) 的最大和
(f[i][j][k]) 为前 (i) 个数中选择 (j) 个且和的余数为 (k) 的最大和
(f[i][j][k] = max(f[i - 1][j][k], f[i - 1][j - 1][(k - a_i) \% p] + a_i))

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

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long LL;
const int N = 100 + 20;
const LL INF = 1e18;

LL f[N][N][N], m;
int n, a[N];

int main()
{
	IOS;
	cin >> n >> m;
	for(int i = 1; i <= n; ++ i) cin >> a[i];
	LL ans = INF;
	for(int p = 1; p <= n; ++ p)
	{
		memset(f, -0x3f, sizeof f);
		f[0][0][0] = 0;
		for(int i = 1; i <= n; ++ i)	
		{
			f[i][0][0] = 0;
			for(int j = 1; j <= p; ++ j)
				for(int k = 0; k < p; ++ k)
					f[i][j][k] = max(f[i - 1][j][k], f[i - 1][j - 1][((k - a[i]) % p + p) % p] + a[i]);
		}
		if(f[n][p][m % p] >= 0) ans = min(ans, (m - f[n][p][m % p]) / p);
	}
	cout << ans << endl;
	return 0;
}
原文地址:https://www.cnblogs.com/ooctober/p/14469555.html