Problem - A - Codeforces
题目大意:给定一个序列,你可以从序列中任取两个数,对前一个数+1,后一个数-1,求通过一定的变换之后如何从序列a成为序列b.如果无法变换,输出-1.
思路:模拟题,主要的关键点在于要注意输出顺序,第一个输出的下标对应的数是-1,第二个数是+1.
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define rep(x,y,z) for(int x = y; x<=z; ++x)
#define dec(x,y,z) for(int x = y; x>=z; --x)
#define INF 0x3f3f3f3f
int t;
int n;
int a[105], b[105];
pair<int, int>c[105];
bool cmp(pair<int, int>& a, pair<int, int>& b) {
return a.first < b.first;
}
int main() {
cin >> t;
while (t--) {
cin >> n;
int suma = 0, sumb = 0;
rep(i, 1, n) { cin >> a[i]; suma += a[i]; }
rep(i, 1, n) { cin >> b[i]; sumb += b[i]; }
rep(i, 1, n) { c[i].first = a[i] - b[i]; c[i].second = i; }
sort(c + 1, c + 1 + n);
int num = 0;
rep(i, 1, n) {
if (c[i].first < 0)num -= c[i].first;
else break;
}
if (suma != sumb) {
cout << -1 << endl;
}
else {
cout << num << endl;
int left = 1, right = n;
while (left < right) {
int temp = min(abs(c[left].first), abs(c[right].first));
rep(i, 1, temp) {
if (c[left].first > 0)
cout << c[left].second << " " << c[right].second <<endl;
else {
cout << c[right].second << " " << c[left].second <<endl;
}
}
if (c[left].first < 0)c[left].first += temp;
else if (c[left].first > 0)c[left].first -= temp;
if (c[right].first < 0)c[right].first += temp;
else if (c[right].first > 0)c[right].first -= temp;
if (c[left].first == 0)left++;
else right--;
}
cout << endl;
}
}
return 0;
}
Problem - B - Codeforces
题目大意:给定若干奇数个相同长度的字符串,每两个字符串凑成一对,一对字符串内可以对任意字符进行交换,当剩下的那个不成对的字符串会被偷走,给定交换后的成对字符串,求出被偷走的字符串.
思路:看似很难,但实际上只需要对每列字符和交换后的字符求一个差,最后剩下来的字符就是被偷走的字符.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(x,y,z) for(int x = y; x<=z; ++x)
#define dec(x,y,z) for(int x = y; x>=z; --x)
#define INF 0x3f3f3f3f
int t, n, m;
const int MAX = 1e5 + 5;
int cur[MAX];
string temp[MAX];
int main() {
cin >> t;
while (t--) {
cin >> n >> m;
memset(cur, 0, sizeof(cur));
rep(i, 0, n - 1) {
cin >> temp[i];
}
rep(i, 0, n - 1) {
rep(j, 0, m - 1) {
cur[j] += (temp[i][j] - 'a');
}
}
rep(i, 0, n - 2)cin >> temp[i];
rep(i, 0, n - 2) {
rep(j, 0, m - 1) {
cur[j] -= (temp[i][j] - 'a');
}
}
rep(i, 0, m - 1) {
char ans = ('a' + cur[i]);
cout << ans;
}
cout << endl;
}
return 0;
}
Problem - C - Codeforces
题目大意:给定一个序列,将原序列排序,看是否符合以下要求:每次交换时只能相邻两个数进行交换,每个数的交换次数必须是偶次数.
思路:因为要满足交换次数是偶数,那么需要对序列进行分类讨论,偶数讨论一组,奇数讨论一组,因为所有的奇数组组内互换是一定符合要求的,同理偶数组也是,对于奇数偶数组进行排序,然后合并到一起,如果合并后的数组是无序的,那么一定无法满足条件.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(x,y,z) for(int x = y; x<=z; ++x)
#define dec(x,y,z) for(int x = y; x>=z; --x)
#define INF 0x3f3f3f3f
int t;
int n;
const int MAX = 1e5 + 5;
vector<int>ans;
vector<int>odd;
vector<int>even;
int main() {
cin >> t;
while (t--) {
ans.clear();
odd.clear();
even.clear();
cin >> n;
int temp;
rep(i, 1, n) {
cin >> temp;
if (i % 2)odd.push_back(temp);
else even.push_back(temp);
}
sort(odd.begin(), odd.end());
sort(even.begin(), even.end());
int numo = odd.size(), nume = even.size();
int pre = 0, left = 0, right = 0;
while (left != numo || right != nume) {
if (left < numo) {
ans.push_back(odd[left++]);
}
if (right < nume)ans.push_back(even[right++]);
}
bool flag = true;
for (auto x : ans) {
if (pre > x) { flag = false; break; }
pre = x;
}
if (flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}