Codeforces Round #630 (Div. 2) (ABC)

Codeforces Round #630 (Div. 2)ABC

A Exercising Walk

水题
题意 就是给你一个起点(x,y),四个数字分别表示左,右,下,上四个方向的移动步数,然后,给你一个范围(x1 <= x <= x2, y1 <=y <= y2)移动过程中必须满足,移动顺序可以任意。
坑点 –菜鸡的自己wa了–
和大多数题的移动方向不一样。
左移动为x-1
右移动为x+1
下移动为y-1
上移动为y+1

#include <cstdio>
#include <cstring>

int T, le, ri, down, up;
int x, y, x1, y1, x2, y2;

int main(){
    
    
	scanf("%d",&T);
	while(T--){
    
    
		scanf("%d%d%d%d", &le, &ri, &down, &up);
		scanf("%d%d%d%d%d%d", &x, &y, &x1, &y1, &x2, &y2);
		if(le && ri && le == ri){
    
    
			if(x - 1 < x1 && x + 1 > x2){
    
    
				printf("No\n");
				continue;
			}
		}
		if(down && up && down == up){
    
    
			if(y - 1 < y1 && y + 1 > y2){
    
    
				printf("No\n");
				continue;
			}
		}
		x += ri - le;
		y += up - down;
		if(x >= x1 && x <= x2 && y >= y1 && y <= y2){
    
    
			printf("Yes\n");
		} else {
    
    
			printf("No\n");
		}
	}
	return 0;
} 

B. Composite Coloring

水题

题意感觉主要是题目比较难理解 对英语菜鸡的自己来说
大意就是 T 组样例, 给你 n 个数,然后找他们的质因子,相同的它们就是是一种颜色(输出的数字相同),不同就换种新颜色(换一个新数字)。
不过输出的数字都必须 大于等于 1,小于等于 11。(题目已经证明颜色个数在11以内,所以从1开始向上加就对了)。
思路
先根据数据范围把可能用到的所有素数给打表,存在 prime 数组里。
然后遍历每一个数,在 prime 数组从左到右找它对应的颜色,颜色用 vis 数组标记是否用过。若没用过那就加一个新颜色,否则就用旧颜色(用过的颜色)。

#include <cstdio>
#include <cstring>

const int N = 1005;
int T, n;
int a[N];
int prime[N], vis[N], sum;
int ans[N];

bool pd(int x){
    
    
    for(int i=2; i*i<=x; i++)
	if(x % i == 0 ) return false;
    return true;
}

int main(){
    
    
    for(int i=2; i<=1000; i++){
    
    
    	if(pd(i)) prime[++sum] = i;
	}   
	scanf("%d",&T);
    while(T--){
    
    
        scanf("%d",&n);
        int cnt = 0;
        memset(vis,0,sizeof(vis));
        for(int i=1; i<=n; i++){
    
    
            scanf("%d",&a[i]);
            for(int j=1; j<=sum; j++) 
			if(a[i] % prime[j] == 0){
    
    
            	if(!vis[j]) {
    
    
					vis[j] = ++cnt;
				}
        		ans[i] = vis[j];
				break;
            }
        }
        printf("%d\n",cnt);
        for(int i=1; i<n; i++) 
		printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

C. K-Complete Word

思维题
回文规律
1 = n
2 = n - 1
3 = n - 2
4 = n - 3
5 = n - 4

周期规律
n 2
1 = 3 = 5 = n - 1
2 = 4 = 6 = n

n 3
1 = 4 = 7 = n - 2
2 = 5 = 8 = n - 1
3 = 6 = 9 = n

n 4
1 = 5 = 9 = n - 3
2 = 6 = 10 = n - 2
3 = 7 = 11 = n - 1
4 = 8 = 12 = n

根据回文串和 k 周期的规律总和,就可以发现
k周期的规律中第 i 个周期都和第 k - i + 1 个周期元素相同然后把他们融合为一组,每一组找到元素数最大的个数 sum,再用应该完全相同的个数 n / k * 2 减去 sum,就是这组应该变的元素数。(若 i == k - i + 1则表明只有一个周期,所以就它自己为一组就行)。

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;

const int N = 2e5 + 10;
char s[N];
int T, n, k; 

int main(){
    
    
	scanf("%d",&T);
	while(T--){
    
    
		map<char,int> mp;
		scanf("%d%d",&n,&k);
		scanf("%s",s+1);
		int ans = 0, sum1 = 0, sum2 = 0;
		for(int i=1; i<=(k+1)>>1; ++i){
    
    
			int l = i, r = k - i + 1;
//			printf("%d %d\n",l,r);
			if(l == r){
    
    
				mp.clear();
				sum1 = 0;
				for(int j=l; j<=n; j+=k){
    
    
					mp[s[j]]++;
					if(mp[s[j]] > sum1){
    
    
						sum1 = mp[s[j]];
					}
				}
				ans += n / k - sum1;
			} else {
    
    
				sum2 = 0;
				mp.clear();
				for(int j=l; j<=n; j+=k){
    
    
					mp[s[j]]++;
					if(mp[s[j]] > sum2){
    
    
						sum2 = mp[s[j]];
					}
				}
				for(int j=r; j<=n; j+=k){
    
    
					mp[s[j]]++;
					if(mp[s[j]] > sum2){
    
    
						sum2 = mp[s[j]];
					}
				}
				ans += n / k * 2 - sum2;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45833169/article/details/109429073