• Codeforces Round #632 (Div. 2) 简要题解


    Codeforces Round #632 (Div. 2)

    A:我用的构造方法是:(n imes m)是奇数就黑白相间涂色,左上角涂(B)(n imes m)是偶数就再把就黑白相间涂色,左上角涂(W),最后把左上角涂(B)

    而这太麻烦,实际上直接第一个格子涂(B)即可。

    int t, n, m, a[N][N]; 
    int main() {
    	scanf("%d", &t);
    	while(t --) {
    		scanf("%d%d", &n, &m);
    		for(int i = 1; i <= n; i ++)
    			for(int j = 1; j <= m; j ++)
    				a[i][j] = (i + j) & 1;
    		if(n * m & 1) {
    			for(int i = 1; i <= n; i ++, puts(""))
    				for(int j = 1; j <= m; j ++)
    					printf("%c", !a[i][j] ? 'B' : 'W');
    			continue ;
    		}
    		a[1][1] = 1;
    		for(int i = 1; i <= n; i ++, puts(""))
    			for(int j = 1; j <= m; j ++)
    				printf("%c", a[i][j] ? 'B' : 'W');
    	}
    	return 0;
    }
    

    B:最优操作顺序肯定是先改后面再改前面。直接判一下即可。

    int n, a[N], b[N];
    int main() {
    	int t; scanf("%d", &t);
    	while(t --) {
    		scanf("%d", &n);
    		for(int i = 1; i <= n; i ++) scanf("%d", a + i);
    		for(int i = 1; i <= n; i ++) scanf("%d", b + i);
    		static bool big[N], small[N]; bool tag = 1;
    		bool bg = 0, sm = 0;
    		for(int i = 1; i <= n; i ++) {
    			big[i] = bg; small[i] = sm;
    			if(a[i] > 0) bg = 1;
    			if(a[i] < 0) sm = 1;
    		}
    		for(int i = 1; i <= n; i ++) {
    			if(a[i] < b[i] && !big[i]) tag = 0;
    			if(a[i] > b[i] && !small[i]) tag = 0;
    		}
    		puts(tag ? "YES" : "NO");
    	}
    	return 0;
    }
    

    C:对于每个位置(i),都会有一个限制表示区间不能包含([l[i], i])。考虑以(i)结尾的合法区间个数是(i - max_{j = 1}^{i}l[j]),求和即可。

    int n;
    ll a[N];
    map<ll, ll> Map; 
    int main() {
    	scanf("%d", &n); ll cnt = 0, up = 0;
    	for(int i = 1; i <= n; i ++) {
    		scanf("%lld", a + i), a[i] += a[i - 1];
    		if(Map[a[i]] || a[i] == 0) {
    			up = max(up, Map[a[i]] + 1);
    		}
    		cnt += i - up;
    		Map[a[i]] = i;
    	}
    	printf("%lld
    ", cnt);
    	return 0;
    }
    

    D:把人的朝向转成01序列。相当于是把一个01序列,每轮可以选若干相邻的(10),然后变成(01)。这就类似冒泡排序的过程,我们先求一个最小轮数的方案,那一定是每轮尽可能多选(10)。然后根据(k)把每轮拆开,直到恰好(k)轮。如果(k)小于最小轮数或大于逆序对数则无解。

    const int N = 3000 + 10;
    int n, k, a[N], ni, pos[N * N], len, bel[N * N];
    char s[N];
    int main() {
    	scanf("%d%d%s", &n, &k, s + 1);
    	for(int i = 1; i <= n; i ++) {
    		a[i] = s[i] == 'R';
    		for(int j = 1; j < i; j ++)
    			ni += a[j] > a[i];
    	}
    	if(k > ni) return puts("-1"), 0;
    	int tmp = 0;
    	while(1) {
    		bool tag = 0; tmp ++;
    		for(int i = 1; i < n; i ++) {
    			if(a[i] && !a[i + 1]) {
    				tag = 1;
    				pos[++ len] = i;
    				bel[len] = tmp;
    			}
    		}
    		if(!tag) break ;
    		for(int i = len; i >= 1 && bel[i] == tmp; i --)
    			swap(a[pos[i]], a[pos[i] + 1]);
    	}
    	tmp --;
    	if(k < tmp) return puts("-1"), 0;
    	int op = tmp, x = -1; //printf("tmp = %d
    ", tmp);
    	for(int i = 1; i <= len && op < k; i ++) {
    		if(bel[i + 1] == bel[i]) {
    			bel[i] = -- x; op ++;
    		}
    	}
    	for(int i = 1, j; i <= len; ) {
    		for(j = i; j < len && bel[j + 1] == bel[i]; j ++) ;
    		printf("%d", j - i + 1);
    		for(int k = i; k <= j; k ++) printf(" %d", pos[k]);
    		puts(""); i = j + 1;
    	}
    	return 0;
    }
    

    E:搬个题解的图:

    首先(nleq 2)无解,车和皇后都不用传送。(n>2)是用下面的方法:我们从大到小填,先填左上角一个(3 imes 3)的方格(如下图)让皇后在其中产生传送,而车不传送。剩下的用蛇形填,把皇后和车一起直接引到(3 imes 3)方格里(引到下图(2)的地方)。

    #include <algorithm>
    #include <cstdio>
    using namespace std;
    const int N = 505;
    int n, a[N][N];
    int main() {
    	scanf("%d", &n);
    	if(n <= 2) return puts("-1"), 0;
    	int t = n * n - 9, cur = 0;
    	a[1][1] = t + 2; a[1][2] = t + 8; a[1][3] = t + 7;
    	a[2][1] = t + 3; a[2][2] = t + 1; a[2][3] = t + 6;
    	a[3][1] = t + 4; a[3][2] = t + 5; a[3][3] = t + 9;
    	for(int i = n; i > 3; i --) {
    		if(i & 1) {
    			for(int j = 1; j <= i; j ++) a[i][j] = ++ cur;
    			for(int j = i - 1; j >= 1; j --) a[j][i] = ++ cur;
    		} else {
    			for(int j = 1; j < i; j ++) a[j][i] = ++ cur;
    			for(int j = i; j >= 1; j --) a[i][j] = ++ cur;
    			
    		}
    	}
    	for(int i = 1; i <= n; i ++, puts(""))
    		for(int j = 1; j <= n; j ++)
    			printf("%d ", a[i][j]);
    	return 0;
    }
    /*
    2 8 7
    3 1 6
    4 5 9
    */
    

    F:对于某个(k)元素最优方案之一,如果某个数的某个非本身因子没出现,那么把这个数换成其因子答案更优。那么一个方案的imperfection就是max 每个数的最大因子。

    于是把(1,2,..,n)除去最小素因子排序(即按非本身最大约数排序)依次选取。可以发现一个数选进去的时候其所有因数(除本身)一定也被选进去过了,那么这就是合法且最优方案。

    const int N = 5e5 + 10;
    int n, c[N];
    bool tag[N];
    int p[N], pc;
    void sieve(int n) {
    	c[1] = 1;
    	for(int i = 2; i <= n; i ++) {
    		if(!tag[i]) p[++ pc] = i, c[i] = i;
    		for(int j = 1; j <= pc && i * p[j] <= n; j ++) {
    			tag[i * p[j]] = 1;
    			if(i % p[j] == 0) {
    				c[i * p[j]] = p[j];
    				break ;
    			}
    			c[i * p[j]] = p[j];
    		}
    	}
    }
    int main() {
    	scanf("%d", &n); sieve(n);
    	for(int i = 1; i <= n; i ++) c[i] = i / c[i];
    	sort(c + 1, c + n + 1);
    	for(int i = 2; i <= n; i ++)
    		printf("%d ", c[i]);
    	return 0;
    }
    
  • 相关阅读:
    vue : 无法加载文件 C:UsersXXXAppDataRoaming pmvue.ps1,因为在此系统上禁止运行脚本
    js全屏和退出全屏浏览器
    js 如何保存代码段并执行以及动态加载script
    计算年龄,精确到年月日
    js闭包问题
    构造函数和继承方法
    js 箭头函数不适用的场景
    获取一组数据的最大值和最小值
    地图
    json传输
  • 原文地址:https://www.cnblogs.com/hongzy/p/12672753.html
Copyright © 2020-2023  润新知