CF1365F 再次交换

1 CF1365F 再次交换

2 题目描述

时间限制 \(2s\) | 空间限制 \(256M\)

\(Ayush, Ashish\)\(Vivek\) 在准备下一轮 \(Codeforces\) 的新题,想检查下他们的测试样例是不是有效。

每个测试样例包括一个整数 \(n\) 和两个大小为 \(n\) 的数组 \(a\)\(b\)。如果按照下面的操作一些次数(可以为零次)后数组 \(a\) 可以转换为数组 \(b\),输入数据任务是有效的,否则是无效的。数组 \(a\) 的操作如下:

  • 选择一个整数 \(k (1≤𝑘≤⌊\frac{n}{2}⌋)\)
  • 交换长度为 \(k\) 的前缀。

例如,如果数组 \(a\) 的初始数据为 \({1,2,3,4,5,6}\),在执行完 \(k=2\) 的操作后,转换为 \({5,6,3,4,1,2}\)。给出一组测试数据,检查每一个是有效的还是无效的。

数据范围:测试样例的组数 \(t: (1≤𝑡≤500)\), 数组的大小 \(n: (1≤𝑛≤500)\), 数组 \(a_i, b_i\) 的个数:\(1≤𝑎_𝑖,b_i≤10^9)\)

3 题解

结论:所有在 \(a\) 数组中对称的数一定在 \(b\) 数组中对称。

证明:对于长度为 \(k\) 的一次交换,位于 \(i\) (不妨设 \(i \le \lfloor \dfrac{n}{2} \rfloor\))的数会变成 \(n - k + i\)。位于 \(n-i+1\) 的数会变成 \(k - (n - (n - i + 1))\),也就是 \(k - i +1\)。而由于 \(n - (n - k + i) + 1\) 也等于 \(k - i + 1\),所以在交换一次后两数仍然对称。由此看来,交换无数次后两数也仍然对称。

我们可以枚举 \(a\) 数组中所有的对称数对,然后在 \(b\) 数组中查找改数对是否出现过。注意我们在 \(b\) 数组找到后要用 \(f\) 数组标记某个位置是否走过。如果我们再次枚举到了枚举到过的位置就需要跳出,否则答案可能错误。需要注意的是吗,对于 \(n\) 为奇数的情况,我们最好特判 \(a\)\(b\) 数组中第\((n+1)/2\) 位是否相同,如果不是则直接跳出。这是因为在题目规定中我们不能改变第 \(\lceil \dfrac{n}{2} \rceil\) 位的值。

4 代码(空格警告):

#include <iostream>
#include <cstring>
using namespace std;
const int N = 505;
int T, n, y, yy;
int a[N], b[N];
int flag, flag2;
bool f[N];
int main()
{
    cin >> T;
    while (T--)
    {
        flag2 = 0;
        memset(f, 0, sizeof(f));
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= n; i++) cin >> b[i];
        if (n % 2 && a[(n+1)/2] != b[(n+1)/2])
        {
            cout << "nO" << endl;
            continue;
        }
        for (int i = 1; i <= n/2; i++)
        {
            y = n-i+1;
            flag = 0;
            for (int j = 1; j <= n/2; j++)
            {
                if (f[j]) continue;
                yy = n-j+1;
                if ((a[i] == b[j] && a[y] == b[yy]) || (a[i] == b[yy] && a[y] == b[j]))
                {
                    f[j] = 1;
                    flag = 1;
                    break;
                }
            }
            if (!flag)
            {
                cout << "nO" << endl;
                flag2 = 1;
                break;
            }
        }
        if (!flag2)
        {
            cout << "yEs" << endl;
            continue;
        }
    }
    return 0;
}

欢迎关注我的公众号:智子笔记

posted @ 2021-03-13 22:30  David24  阅读(57)  评论(0编辑  收藏  举报