Codeforces Round #630 (Div. 2) 题解
A. Exercising Walk
-
题意
限定 x , y x,y x,y的范围,给出初始坐标和需要向各个方向行走的次数,问是否符合。 -
解题思路
首先,如果 [ x 1 , x 2 ] [x_1,x_2] [x1,x2]的长度大于 0 0 0,那么我们可以在里面反复横跳抵消掉 m i n ( a , b ) min(a,b) min(a,b),那么其中一个就会变为 0 0 0,只需要判断再走会不会超出边界,同理对于 [ y 1 , y 2 ] [y_1,y_2] [y1,y2]同理。需要注意的一点就是要特判当 x 1 = x 2 , y 1 = y 2 x_1=x_2,y_1=y_2 x1=x2,y1=y2的时候,此时不能行走,如果 a , b , c , d > 0 a,b,c,d>0 a,b,c,d>0就不符合。 -
AC代码
/**
*@filename:A
*@author: pursuit
*@created: 2021-08-11 14:29
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n;
int a,b,c,d;//a次左,b次右,c次下,d次上。
int x,y,x1,Y1,x2,y2;
void solve(){
//左和右可以相互抵消。
int temp1 = min(a,b),temp2 = min(c,d);
if((x == x1 && x == x2 && (b > 0 || a > 0)) ||
(y == Y1 && y == y2 && (c > 0 || d > 0))){
puts("No");
return;
}
a -= temp1,b -= temp1,c -= temp2,d -= temp2;
bool flag = false;
if(x - x1 < a || x2 - x < b || y - Y1 < c || y2 - y < d){
flag = true;
}
if(flag){
puts("No");
}
else{
puts("Yes");
}
}
int main(){
scanf("%d", &t);
while(t -- ){
scanf("%d%d%d%d", &a, &b, &c, &d);
scanf("%d%d%d%d%d%d", &x, &y, &x1, &Y1, &x2, &y2);
solve();
}
return 0;
}
B. Composite Coloring
-
题意
给你一些合数,你可以使用最多 11 11 11种颜色染色,其中需要满足,每个元素都需要染色,相同颜色的元素其 g c d gcd gcd一定要大于 1 1 1。 -
解题思路
我们需要注意, a i ≤ 1000 a_i\leq 1000 ai≤1000,而其又是合数,说明存在 ≤ ⌊ s q r t ( 1000 ) = 32 \leq \lfloor sqrt(1000) = 32 ≤⌊sqrt(1000)=32的因子,而其中质因子正好是 11 11 11个,据此,则可知,我们只需要对不同的质因子倍数染不同的色即可。 -
AC代码
/**
*@filename:B
*@author: pursuit
*@created: 2021-08-11 14:49
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e3 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n,a[N],c[] = {2,3,5,7,11,13,17,19,23,29,31};
map<int,int> p;
void solve(){
int cnt = 0;
for(int i = 1; i <= n; ++ i){
for(int j = 0; j < 11; ++ j){
if(a[i] % c[j] == 0){
if(!p[c[j]]){
p[c[j]] = ++ cnt;
}
a[i] = p[c[j]];
break;
}
}
}
printf("%d\n", cnt);
for(int i = 1; i <= n; ++ i){
printf("%d ", a[i]);
}
puts("");
}
int main(){
scanf("%d", &t);
while(t -- ){
scanf("%d", &n);
p.clear();
for(int i = 1; i <= n; ++ i){
scanf("%d", &a[i]);
}
solve();
}
return 0;
}
C. K-Complete Word
-
题意
给定一个字符串 s s s,需要将字符串 s s s变成 k k k完整字符串,即符合 s s s是回文串, s s s存在 k k k周期长度相等。问最小花费。 -
解题思路
根据这个特性,我们发现每个周期都是回文字符串,所以我们根据这个特性,跨度取必须要相等的统计其字符出现次数即可,然后计算最小修改次数。 -
AC代码
/**
*@filename:C
*@author: pursuit
*@created: 2021-08-11 15:46
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 2e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n,k;
char s[N];
int cnt[26];
void solve(){
int ans = 0;
for(int l = 0,r = k - 1; l <= r; l ++ , r --){
//cout << l << " " << r << endl;
for(int i = l, j = r; i < n; i += k, j += k){
cnt[s[i] - 'a'] ++;
cnt[s[j] - 'a'] ++;
}
int maxx = 0;
for(int i = 0; i < 26; ++ i){
maxx = max(cnt[i],maxx);
cnt[i] = 0;
}
if(l == r){
ans += n / k - maxx / 2;
}
else{
ans += n / k * 2 - maxx;
}
}
printf("%d\n", ans);
}
int main(){
scanf("%d", &t);
while(t -- ){
scanf("%d%d", &n, &k);
scanf("%s", s);
solve();
}
return 0;
}
D. Walk on Matrix
-
题意
给定用DP计算的矩阵错误异或和与正确异或和的差值,构造这样一个矩阵。 -
解题思路
我们知道,这种 D P DP DP对于KaTeX parse error: Expected 'EOF', got '&' at position 1: &̲运算是不适用的,因为局部最优不一定可以构成全局最优,不符合最优子结构的特征。我们可以构造一个 2 × 3 2\times 3 2×3的矩阵,其中以一个最大值 a = 1 < < 17 a=1<<17 a=1<<17,然后构造形如
a + k , k , 0 a , a + k , k a +k,k,0\\a,a+k,k a+k,k,0a,a+k,k。这样, D P DP DP方法在 ( 2 , 2 ) (2,2) (2,2)处是取得 k k k,这样得到得结果是 0 0 0,而最大值实际上是 k k k,符合题目要求。 -
AC代码
/**
*@filename:D
*@author: pursuit
*@created: 2021-08-11 16:35
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 500 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int k,a = 1 << 17;
void solve(){
printf("2 3\n");
printf("%d %d %d\n", a + k, k , 0);
printf("%d %d %d\n", a, a + k, k);
}
int main(){
scanf("%d", &k);
solve();
return 0;
}

浙公网安备 33010602011771号