Codeforces Round #732 (Div. 2)题解

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值