Codeforces Round #587 (Div. 3) A B C D E1

传送门

A:签到

#include
using namespace std;
typedef long long ll;
const int N = 2e5+10;

int n;
char s[N];
int num;
int main(){
	scanf("%d%s", &n, s+1);
	int cnt = 0;
	for(int i = 1; i <= n; i++){
		if(s[i] == 'a'){
			num++;
		}
		if(i%2 == 0){
			if(num != i - num){
				cnt++;
				if(s[i] == 'a'){
					s[i] = 'b';
					num--;
				}
				else{
					num++;
					s[i] = 'a';
				}
			}
		}
	}
	printf("%d\n%s\n", cnt, s+1);
	return 0;
}

B:贪心,先取大的

#include
using namespace std;
typedef long long ll;
const int N = 1e3+10;

int n;
struct node{
	int a, num;
	bool operator < (const node& x)const{
		return a > x.a;
	}
}e[N];
int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d", &e[i].a);
		e[i].num = i;
	}
	sort(e+1, e+1+n);
	ll ans = 0;
	for(int i = 1; i <= n; i++){
		ans += e[i].a * (i-1) + 1;
	}
	printf("%lld\n", ans);
	for(int i = 1; i <= n; i++){
		printf("%d%c", e[i].num,i==n?'\n':' ');
	}
	return 0;
}

C: 扩点、加点、离散化,然后暴力染色

#include
using namespace std;
typedef long long ll;

int x[10], y[10];
int a[10], b[10];
int m[20][20];
int main(){
	int cnt = 0;
	for(int i = 1; i <= 6; i++){
		scanf("%d%d", &x[i], &y[i]);
		x[i] = x[i]*2, y[i] = y[i]*2;
		a[++cnt] = x[i], b[cnt] = y[i];
		a[++cnt] = x[i]+1, b[cnt] = y[i]+1;
	}
	sort(a+1, a+1+cnt);
	sort(b+1, b+1+cnt);
	int lena = unique(a+1, a+1+cnt) - a - 1;
	int lenb = unique(b+1, b+1+cnt) - b - 1;
	for(int i = 1; i <= 6; i++){
		x[i] = lower_bound(a+1, a+1+lena, x[i]) - a;
		y[i] = lower_bound(b+1, b+1+lenb, y[i]) - b;
	}
	for(int i = x[1]; i <= x[2]; i++){
		for(int j = y[1]; j <= y[2]; j++){
			m[i][j] = 1;
		}
	}
	for(int i = x[3]; i <= x[4]; i++){
		for(int j = y[3]; j <= y[4]; j++){
			m[i][j] = 2;
		}
	}
	for(int i = x[5]; i <= x[6]; i++){
		for(int j = y[5]; j <= y[6]; j++){
			m[i][j] = 2;
		}
	}
	for(int i = 1; i <= lena; i++){
		for(int j = 1; j <= lenb; j++){
			if(m[i][j] == 1){
				printf("YES\n");
				return 0;
			}
		}
	}
	printf("NO\n");
	return 0;
}

D: 所有被盗取不同种类剑数的gcd即为每个人盗取的剑。

#include
using namespace std;
typedef long long ll;
const int N = 2e5+10;

int n;
int a[N];
int main(){
	scanf("%d", &n);
	int ma = 0;
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		ma = max(ma, a[i]);
	}
	int gcd = 0;
	ll sum = 0;
	for(int i = 1; i <= n; i++){
		a[i] = ma - a[i];
		sum += a[i];
		gcd = __gcd(gcd, a[i]);
	}
	ll ans = sum/gcd;
	printf("%lld %d", ans, gcd);
	return 0;
}

E1:最后绝杀, 代码巨丑, 把每个连续块长度计算出来, 对处理连续块长度的前缀和,每次查询找到查询所处的块,暴力查找。

#include
using namespace std;
typedef long long ll;
const int N = 2e5+10;

int q;
ll a[N], b[N];
vector v;
int main(){
	scanf("%d", &q);
	for(int i = 1; i < N; i++){
		int pp = 0, qq = i;
		while(qq){
			pp++;
			qq /= 10;
		}
		b[i] += b[i-1]+pp;
	}
	for(int i = 1; i < N; i++){
		a[i] += a[i-1]+b[i];
	}
	int k;
	while(q--){
		scanf("%d", &k);
		int i = 1;
		for(; i <= N; i++){
			if(a[i] >= k) break;
		}
		int cnt = 1;
		//cout << "..." << k - a[i-1] << "\n";
		for(int j = 1; j <= k - a[i-1]; j++){
			int tmp = j;
			int p = 0;
			int flag = 0;
			int tt = 1;
			v.clear();
			while(tmp){
				v.push_back(tmp%10);
				if(cnt == k - a[i-1]){
					flag = tt;
				}
				tt++;
				cnt++;
				tmp /= 10;
			}
			//cout << cnt << " " << k-a[i-1] << "\n";
			if(flag) {
				printf("%d\n", v[v.size()-flag]);
				break;
			}
		}
	}
	return 0;
}

 

你可能感兴趣的:(codeforces)