【CF】Day26——Teza Round 1 (Codeforces Round 1015, Div. 1 + Div. 2) CD

C. You Soared Afar With Grace

题目:

思路:

很有意思的模拟题,代码细节需注意

因为题目没要求我们最小步骤什么的,同时n也比较小,所以按照题意模拟即可,但是注意细节,比如数的位置,奇偶性,特殊情况等

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n+1),b(n+1);
    vector<int> bpos(n+1,0);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    int flag = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> b[i];
        flag |= (b[i] != a[n+1 - i]);
        bpos[b[i]] = i;
    }
    if (!flag)
    {
        cout << "0\n";
        return;
    }
    int num = 0;
    vector<pair<int, int>> ans;
    for (int i = 1; i <= n; i++)
    {
        if (a[bpos[a[i]]] != b[i])
        {
            cout << "-1\n";
            return;
        }
        if (a[i] == b[i])
        {
            if (n % 2 == 0 || num)
            {
                cout << "-1\n";
                return;
            }
            num = i;
        }
    }
    auto change = [&](int x,int y) {
        if (x == y)
        {
            return;
        }
        ans.push_back({ x,y });
        swap(a[x], a[y]);
        swap(b[x], b[y]);
        swap(bpos[b[x]], bpos[b[y]]);
        };
    if (num)
    {
        change(num, (n + 1) / 2);
    }
    for (int i = 1; i <= n / 2; i++)
    {
        change(bpos[a[i]], n + 1 - i);
    }
    cout << ans.size() << endl;
    for (auto x : ans)
        wcout << x.first << " " << x.second << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D. Arcology On Permafrost

题目:

思路:

需要一点观察的构造题

 我们最优的解法肯定是构造出一个类似与于 0 1 2 ... d 0 1 2 ... d 0 1 ... 这样的序列,其中任意一个数字都要出现 m + 1 次,这样才能保证最后能剩下这个数,同时相同的数一定要间隔 k ,这样才能保证不会一次删除两个的情况

所以这个 d 的最大值就是 n / (m + 1) - 1 (要包含0),间隔就是 max(d,k)

代码还是很好写的

代码:

#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "YES\n"
#define no cout << "NO\n"

void solve()
{
    int n, m, k;
    cin >> n >> m >> k;
    vector<int> ans(n);
    int d = n / (m + 1);
    for (int i = 0; i < d; ++i) 
    {
        for (int j = i; j < n; j += max(k, d))
        {
            ans[j] = i;
        }
    }
    for (int i = 0; i < n; ++i) 
    {
        cout << ans[i] << " ";
    }
    cout << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值