2023/03/07刷题
B. Odd Sum Segments
链接
这个题还是比较好写的,直接统计一下数组里面的奇数的个数就可以判断能不能划分出来合适的区间了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 200008;
int a[N];
void solve() {
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
vector<int> res;
for (int i = 1; i <= n; i++) {
if (a[i] % 2 == 1) {//将a[i]里面奇数加入res数组
res.push_back(i);
}
}
if (res.size() < k) {//如果奇数的个数比k还少打印no
no;
} else {//如果个数比奇数多的话分类讨论一下
int num = res.size() - (k - 1);//让res.size减去(k-1)之后看一下还剩多少个奇数
if (num % 2 == 1) {//如果有奇数个奇数,肯定可以成立
yes;
for (int i = 0; i < k - 1; i++) {//先打印前k-1个奇数的下标
cout << res[i] << ' ';
}
cout << n << '\n';//最后打印一个n
} else {//如果剩下的奇数是偶数个的话打印no
no;
}
}
}
signed main () {
int t;
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}
B. Make Them Equal
链接
这个题我们可以发现,因为只有三种情况,所以当数组排序并且去重之后最多有三个元素,然后我们对1个元素,2个元素,3个元素的情况进行分别判断
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 105;
int a[N];
signed main () {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);//先排序
n = unique(a, a + n) - a;//去重,并且数组去重之后的长度为n
vector <int> res;
for (int i = 0; i < n; i++) {
res.push_back(a[i]);//将这个数组存入vector
}
if (n > 3) {//大于3输出-1
cout << -1 << '\n';
} else {
//因为我们要给出D的最小值
if (n == 2) {//为2,先判断第一个元素和最后一个元素的差能否被2整除
if ((res.back() - res[0]) % 2 == 0) {
cout << (res.back() - res[0]) / 2;//整除打印差值除以2
} else {
cout << (res.back() - res[0]);//不能整除打印差值
}
} else if (n == 3 && (res[2] - res[0]) == 2 * (res[1] - res[0])) {//当n=3的时候判断第一个数和最后一个数的差值是不是前两个数差值的二倍
//如果是打印第一个数和最后一个数的差除以2的结果
cout << (res.back() - res[0]) / 2;
} else if (n == 1) {//只有一个元素打印0
cout << 0;
} else {//其他情况打印-1
cout << -1 << '\n';
}
}
return 0;
}
C. Double Sort
链接
这个题很也是不会,看了题解才会的,就是先用a的排序方式对a,b都排序,然后在排序b数组,如果b数组出现交换位置的时候判断a数组两个位置是不是相等,如果相等可以交换,不相等打印-1
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstring>
#include <unordered_set>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <sstream>
#include <queue>
#define int long long
#define yes cout<<"YES"<<'\n'
#define no cout<<"NO"<<'\n'
using namespace std;
const int N = 105;
int a[N], b[N];
struct data {
int x, y;
};
void solve() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
cin >> b[i];
}//读入数据
vector <struct data> res;//储存每次交换位置的下标
int len = n;
int cnt = 0;
while (len != 1) {//冒泡排序
len--;
for (int i = 0; i < len; i++) {//按照a数组进行排序
if (a[i] > a[i + 1]) {
swap(a[i], a[i + 1]);
swap(b[i], b[i + 1]);//交换a数组和b数组
struct data temp;
temp.x = i + 1;//因为下标从0开始所以要存入下标加1
temp.y = i + 2;
res.push_back(temp);
cnt++;
}
}
}
len = n;
while (len != 1) {//按照b数组进行排序
len--;
for (int i = 0; i < len; i++) {
if (b[i] > b[i + 1]) {
if (a[i] == a[i + 1]) {//如果b数组要交换位置,a数组的两个数必须相同
swap(a[i], a[i + 1]);
swap(b[i], b[i + 1]);//如果相同将结果放入res
struct data temp;
temp.x = i + 1;
temp.y = i + 2;
res.push_back(temp);
cnt++;//计数器加1
} else {
cout << -1 << '\n';//否则打印-1
return;
}
}
}
}
cout << cnt << '\n';//如果排序完成,打印cnt
for (int i = 0; i < res.size(); i++) {
cout << res[i].x << ' ' << res[i].y << '\n';//打印每次的交换索引
}
}
signed main () {
int t;
ios::sync_with_stdio(false);
cin >> t;
while (t) {
solve();
t--;
}
return 0;
}