Educational Codeforces Round 26

A

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 200 + 10;
char st[qq];

int main(){
	int n;	scanf("%d", &n);
	getchar();
	gets(st);
	int maxn = 0;
	string x = "";
	int cnt = 0;
	for(int i = 0; i < n; ++i) {
		if(isalpha(st[i])) {
			if(isupper(st[i]))	cnt++;
			x += st[i];
		} else {
			maxn = max(maxn, cnt);
			cnt = 0;
		}
	}
	maxn = max(maxn, cnt);
	printf("%d\n", maxn);
	return 0;
}

B

题意:整个图是三条条纹状,每个颜色是一条条纹。

思路:分别找出R、B、G三种颜色的左上角和右下角,如果成条纹状那么整个区域肯定得是同一种颜色,并且大小得相同,三条条纹大小得相等

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 105 + 10;
char st[qq][qq];
int n, m;
int width[qq], heigh[qq];
bool f = true;
void Check(char ch) {
	int x1, y1, x2, y2;
	x1 = y1 = 1e9;
	x2 = y2 = -1e9;
	for(int i = 1; i <= n; ++i) {
		for(int j = 1; j <= m; ++j) {
			if(st[i][j] == ch) {
				x1 = min(x1, i);
				y1 = min(y1, j);
				x2 = max(x2, i);
				y2 = max(y2, j);
			}
		}
	}
	for(int i = x1; i <= x2; ++i) {
		for(int j = y1; j <= y2; ++j) {
			if(st[i][j] != ch) {
				f = false;
			}
		}
	}
	if(ch == 'R') {
		width[1] = x2 - x1;
		heigh[1] = y2 - y1;
	} else if(ch == 'B') {
		width[2] = x2 - x1;
		heigh[2] = y2 - y1;
	} else {
		width[3] = x2 - x1;
		heigh[3] = y2 - y1;
	}
}

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		scanf("%s", st[i] + 1);
	}
	Check('R'), Check('B'), Check('G');
	if(!f) {
		puts("NO");
		return 0;
	}
	if(width[1] == width[2] && width[2] == width[3] && heigh[1] == heigh[2] && heigh[2] == heigh[3]) {
		puts("YES");
	} else {
		puts("NO");
	}
	return 0;
}

C

题意:给出n个矩形的左上角和右下角,给出一个a * b的矩形,问你再在n个中选两个放入a * b的矩形要求被占据的面积最大

思路:枚举,然后判断是否能放下

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int> 
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 105 + 10;
pill node[qq];
bool Check(int a, int b, int x1, int y1, int x2, int y2) {
	if(x1 <= a && y1 <= b && (a - x1) >= x2 && b >= y2)	return true;
	if(x1 <= a && y1 <= b && x2 <= a && (b - y1) >= y2)	return true;
	if(x1 <= a && y1 <= b && y2 <= a && (b - y1) >= x2)	return true;
	if(x1 <= a && y1 <= b && x2 <= b && (a - x1) >= y2)	return true;
	if(y1 <= a && x1 <= b && (b - x1) >= x2 && y2 <= a)	return true;
	if(y1 <= a && x1 <= b && x2 <= b && (a - y1) >= y2)	return true;
	if(y1 <= a && x1 <= b && y2 <= b && (a - y1) >= x2)	return true;
	if(y1 <= a && x1 <= b && y2 <= (b - x1) && x2 <= a)	return true;
	return false;
}

int main(){
	int n, a, b;	scanf("%d%d%d", &n, &a, &b);
	if(a > b)	swap(a, b);
	for(int i = 0; i < n; ++i) {
		int x, y;
		scanf("%d%d", &x, &y);
		if(x > y)	swap(x, y);
		node[i] = mk(x, y);
	//	if(node[i].first > node[i].second)	swap(node[i].first, node[i].second);
	}
	int maxn = 0;
	for(int i = 0; i < n; ++i) {
		for(int j = i + 1; j < n; ++j) {
			if(a * b < node[i].first * node[i].second + node[j].first * node[j].second)	continue;
			if(Check(a, b, node[i].first, node[i].second, node[j].first, node[j].second)) {
				maxn = max(maxn, node[i].first * node[i].second + node[j].first * node[j].second);
			}
		}
	}
	printf("%d\n", maxn);
	return 0;
}



D

题意:n个数中选k个使得最后乘积含0最多

思路:很显然这题不是简单的贪心,如果一个数是5^15 ,一个数是2^20,那么他们乘积后由15个0,先预处理出每个数含因子2和5的个数,然后dp[i][j] = k,表示选i个因子5个数为j的情况下含最多的5是k

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 5500 + 10;
int n, k;
struct Node {
	int two;
	int five;
}node[qq];
int Cal(LL x, int id) {
	int a = 0;
	while(x % 2 == 0) {
		a++;
		x /= 2;
	}
	int b = 0;
	while(x % 5 == 0) {
		b++;
		x /= 5;
	}
	node[id].two = a;
	node[id].five = b;
}
int dp[205][qq];
int main(){
	scanf("%d%d", &n, &k);
	int maxnX, maxnY;
	maxnY = maxnX = 0;
	for(int i = 0; i < n; ++i) {
		LL x;
		scanf("%lld", &x);
		Cal(x, i);
		maxnX += node[i].two;
		maxnY += node[i].five;
	}
	mst(dp, -1);
	dp[0][0] = 0;
	for(int i = 0; i < n; ++i) {
		for(int j = k; j >= 1; --j) {
			for(int t = maxnY; t >= 0; --t) {
				if(t - node[i].five < 0)	break;
				if(dp[j - 1][t - node[i].five] == -1)	continue;
				dp[j][t] = max(dp[j][t], dp[j - 1][t - node[i].five] + node[i].two);
			}
		}
	}
	int ans = 0;
	for(int i = 0; i <= maxnY; ++i) {
		if(dp[k][i] == -1)	continue;
		ans = max(ans, min(i, dp[k][i]));
	}
	printf("%d\n", ans);
	return 0;
}


E

参考:传送门

#include <cstdio>
#include <cstring>
#include <cmath>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <utility>

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define pill pair<int, int>
#define ft first
#define sd second
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int qq = 1e5 + 10;
const int MOD = 1e9 + 7;
LL x, y;
LL Gcd(LL a, LL b) {
	return b == 0 ? a : Gcd(b, a % b);
}

int main(){
	scanf("%lld%lld", &x, &y);
	LL g = Gcd(x, y);
	x /= g, y /= g;
	vector<LL> a;
	for(LL i = 2; i * i <= x; ++i) {
		while(x % i == 0) {
			x /= i;
			a.pb(i);
		}
	}
	if(x > 1)	a.pb(x);
	LL ans = 0;
	while(y > 0) {
		LL minx = y;
		for(LL i : a) {
			minx = min(minx, y % i);
		}
		ans += minx;
		y -= minx;
		vector<LL> b;
		for(LL i : a) {
			if(y % i == 0) {
				y /= i;
			} else {
				b.pb(i);
			}
		}
		a.swap(b);
	}
	printf("%lld\n", ans);
 	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值