这一场div2只A了两题 竟然加了70多分orz(肯定是基础分太低
A.Exercising Walk
题意:
向左走a步,向右走b步,向下走c步,向上走d步,问能否在执行所有操作的过程中始终处于题目给的范围内
思路:
只需判断同方向移动步数的代数和是否满足条件即可,注意特判下x1 == x2 和 y1 == y2的情况
这里我们用ta和tb代表一对相反方向的差
对于ta 为什么用b-a而不用a-b呢
可以这样思考 b-a为向右移动的步数
当b-a大于0时代表最终向右移动 此时x+ta恰好比x大 也代表向右移动 如果ta取a-b 就达不到这种效果 tb同理
当x1 == x2 时 在水平方向上不能移动 此时之后a == b == 0是符合要求的 所以特判x1 == x2 和 y1 == y2 的情况
ps(x2>=x1, y2>=y1,本蒟蒻没看到条件orz)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<cstdio>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int maxn = 1e3+10;
int main() {
int a, b, c, d;
int x, y, x1, y1, x2, y2;
int t;cin >> t;
while (t--) {
cin >> a >> b >> c >> d;
cin >> x >> y >> x1 >> y1 >> x2 >> y2;
int flag = 1;
int ta = b - a;
int tb = d - c;
ta += x;
tb += y;
if ((x1 == x2 && (a || b)) || (y1 == y2 && (c || d)))printf("NO\n");
else if (ta >= x1 && ta <= x2 && tb >= y1 && tb <= y2)printf("YES\n");
else printf("NO\n");
}
}
B.Composite Coloring
题意
给一个长度不超过1000的数组,每个数不超过1000且为合数,如果两个数不互质这这两个数颜色相同,且一个数只能有一种颜色,不同颜色数1<= m <= 11,且颜色不能出现断层 即m之前的所有数都要出现(m取5 那么1,2,3,4,5都要出现)
思路:
可以发现第11个素数31 * 31 < 1000 但31 * 37 > 1000,很容易想到,前1000个整数都可以被11个素数中的一个整除,可以用set存出现的不同最小质因数的种类 vis记录每个最小值引述对应的编号 vis[a[i]]就表示这个质因数对应的编号 输出即可
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<map>
#include<cstdio>
#include<set>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int maxn = 1e3+10;
int a[maxn];
int ans[maxn];
int b[13] = { 0,2,3,5,7,11,13,17,19,23,29,31 };
int vis[20];
int main() {
int t;cin >> t;
while (t--) {
set<ll>s;
memset(a, 0, sizeof(a));
memset(vis, 0, sizeof(vis));
memset(ans, 0, sizeof(ans));
int n;cin >> n;
for (int i = 1;i <= n;++i) {
cin >> a[i];
}
for (int i = 1;i <= n;++i) {
for (int j = 1;j <= 11;++j) {
if (a[i] % b[j] == 0) {
a[i] = j;
s.insert(j);
break;
}
}
}
cout << s.size() << endl;
ll k = 0;
for (auto i : s) {
vis[i] = ++k;
}
for (int i = 1;i <= n;++i) {
cout << vis[a[i]] << " ";
}
}
}
C. K-Complete Word
题意:
一个长度为n的字符串,分成k个部分要求这k个子字符串都相同且为回文串
求最小修改操作数
##思路
既然是回文串那么每一部分的i和k-i-1位置上的字符串是相同的,看一下哪个字幕出现的次数最多就用哪个字母
i == k-i-1时只需要搜索一次,其他情况两次
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 1000000007
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
char s[maxn];
int main() {
int t;cin >> t;
while (t--) {
int n, k;cin >> n >> k;
cin >> s;
int ans = n;
for (int i = 0;i <= k - i - 1;++i) {
vector<int>a(26, 0);//定义一个具有26个整型变量的vector数组,并初始化为0
//i == k-i-1时只需要搜索一次
for (int j = i;j < n;j += k) {
a[s[j] - 'a']++;
}
if (i < k - i - 1) {
for (int j = k - i - 1;j < n;j+=k) {
a[s[j] - 'a']++;
}
}
ans -= *max_element(a.begin(), a.end());//减去不需要修改的
}
printf("%d\n", ans);
}
}