首页 > 代码库 > Codeforces Round #246 (Div. 2)

Codeforces Round #246 (Div. 2)

题目链接:CF|Round246|DIV2

赛后两分钟才搞出C。。

真是逗比。

A:简单统计。时间复杂度:O(N)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2010;
int a[N];

int main(){
    int n, k;
    scanf("%d%d", &n, &k);
    int cnt = 0;
    for(int i = 0; i < n; ++i){
        int x;
        scanf("%d", &x);
        if(5 - x >= k) ++cnt;
    }
    printf("%d\n", cnt / 3);
    return 0;
}

B:数据较大, 简单模拟会超时。 能够考虑,作为一个队主场(n-1)场肯定是主队,还有可能的是当该队客场比赛时, 颜色与主队一样。 这样仅仅要hash一下同种颜色的主队个数就可以。

最后能够依据总的比赛数 - 主队的次数得到客队的次数。时间复杂度O(N)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int x[N];

int main(){
    int n, k;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i){
        scanf("%d%d", &a[i], &b[i]);
        ++x[a[i]];
    }

    for(int i = 0; i < n; ++i){
        int ans = n - 1 + x[b[i]];
        if(a[i] == b[i]) ans -= 1;
        printf("%d %d\n", ans, n*2 - 2 - ans);
    }
    return 0;
}

C:乱搞题。

题意非常easy。 就是能够互换之间相隔为质数个数的数字,得到 一个有序的序列。

YY了一个定理:随意一个数都能够由最多5个质数的和表示(原来是哥德巴赫猜想:囧)。 刚好最大操作个数<=5*n。

这样先预处理出全部的素数, 每次二分素数, 推断并进行交换。  时间复杂度:O(N*sqrt(N))

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e6 + 1;
bool isPrime[N];
int a[N], prime[N];
int p[N];
int cnt;
int x[N], y[N];

void gao(){
	int k = sqrt(N*1.0);
	int i = 2;
	while(i <= k){
		for(int j = i*i; j < N; j += i) isPrime[j] = 1;
		++i;
		while(i <= k && isPrime[i]) ++i;
	}

	for(int i = 2; i < N; ++i){
		if(!isPrime[i]) prime[cnt++] = i;
	}
}

int foo(int k){
	int l = 0, r = cnt - 1;
	while(l < r){
		int m = (l + r + 1) >> 1;
	//	printf("m = %d\n", m);
		if(prime[m] <= k) l = m;
		else r = m - 1;
	}
	return l;
}

int main(){
	int n;
	scanf("%d", &n);
	gao();
//	for(int i = 0; i < 30; ++i) printf("%d  ", prime[i]);
	for(int i = 1; i <= n; ++i){
		scanf("%d", &a[i]);
		p[a[i]] = i;
	}
 //   foo(3);
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		int dif = abs(p[i] - i) + 1;
		if(p[i] > i){
			int tmp = dif;
			int xx = p[i], yy = i;
			while(tmp != 0){
	//			printf("%d en\n", tmp);

				int k = foo(tmp);
		//		printf("%d\n",foo(tmp));
				x[ans] = xx, y[ans] = xx - prime[k] + 1;
				p[a[y[ans]]] = xx;
				swap(a[xx], a[y[ans]]);
			    tmp -= prime[k];
				if(tmp != 0) tmp += 1;
				xx = y[ans++];
			}
		}
		else if(i > p[i]){
			int tmp = dif;
			int xx = p[i], yy = i;
			while(tmp != 0){
				int k = foo(tmp);
				x[ans] = xx, y[ans] = xx + prime[k] - 1;
				p[a[y[ans]]] = xx;
				swap(a[xx], a[y[ans]]);
			    tmp -= prime[k];
				if(tmp) ++tmp;
				xx = y[ans++];
			}
		}
	}
	printf("%d\n", ans);
	for(int i = 0; i < ans; ++i){
		if(x[i] < y[i]) printf("%d %d\n", x[i], y[i]);
		else  printf("%d %d\n", y[i], x[i]);
	}
	return 0;
}


Codeforces Round #246 (Div. 2)