专栏文章

题解:UVA1697 Baggage

UVA1697题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miojeyle
此快照首次捕获于
2025/12/02 20:11
3 个月前
此快照最后确认于
2025/12/02 20:11
3 个月前
查看原文
首先我们知道达到终态需要满足相邻元素相同的对数为 2×(n1)2\times(n-1),初态为 00 对,操作过程中除第一次操作外(11 对)其余每次最多产生 22 对,所以答案的下界为 nn。考虑如何构造达到下界的方案。
先手模样例,以 n=8n=8 为例,按如下步骤置换:
__BABABABABABABABAABBABABABABABAB__AABBA__BABABABABBAA\texttt{\textcolor{blue}{\_\_}BABABABABABABABA}\\ \texttt{\textcolor{red}{AB}BABABABABABAB\textcolor{blue}{\_\_}A}\\ \texttt{ABBA\textcolor{blue}{\_\_}BABABABAB\textcolor{red}{BA}A}\\
此时,中间的 __BABABABA\texttt{\textcolor{blue}{\_\_}BABABABA} 变成了一个类似的子问题,长度为 n4n-4。我们继续往下递归,直到中间部分有序:
ABBAAAAABBBB__BBAA\texttt{ABBA\textcolor{red}{AAAABBBB}\textcolor{blue}{\_\_}BBAA}
继续构造。
A__AAAAABBBBBBBBAAAAAAAAAABBBBBBBB__\texttt{A\textcolor{blue}{\_\_}AAAAABBBB\textcolor{red}{BB}BBAA}\\ \texttt{A\textcolor{red}{AA}AAAAABBBBBBBB\textcolor{blue}{\_\_}}\\
可以从上例中发现一个更为通用的解法:
__BA|BA...BA|BABAABBA|BA...BA|B__AABBA|__...BA|BBAA...ABBA|AAAA...BB__|BBAAA__A|AAAA...BBBB|BBAAAAAA|AAAA...BBBB|BB__\texttt{\_\_BA|BA...BA|BABA}\\ \texttt{\textcolor{red}{AB}BA|BA...BA|B\textcolor{blue}{\_\_}A}\\ \texttt{ABBA|\textcolor{blue}{\_\_}...BA|B\textcolor{red}{BA}A}\\ ...\\ \texttt{ABBA|AAAA...BB\textcolor{blue}{\_\_}|BBAA}\\ \texttt{A\textcolor{blue}{\_\_}A|AAAA...BB\textcolor{red}{BB}|BBAA}\\ \texttt{A\textcolor{red}{AA}A|AAAA...BBBB|BB\textcolor{blue}{\_\_}}\\
考虑 n=3n=3 的情况,模拟可以发现,我们无法在左侧拓展 22 格的条件下完成转移,特判一下即可。
初始时有 2n2n 个位置,我们每次递归需要隔离出 88 个位置,我们要保证下一次递归序列有效需满足 2n88,n82n-8\ge8,n\ge8。如果 n[3,7]n \in [3,7],则 n43n-4\le3 方案对此序列无效。所以对于 n8n\ge 8 的序列进行递归操作,3n73\le n \le 7 的序列直接打表输出方案即可。
CPP
void work(int l, int r) {
    if (r - l + 1 == 8) {
        cout << r - 2 << " to " << l - 2 << endl;
        cout << l + 2 << " to " << r - 2 << endl;
        cout << l - 1 << " to " << l + 2 << endl;
        cout << r - 1 << " to " << l - 1 << endl;
    } else if (r - l + 1 == 10) {
        cout << r - 2 << " to " << l - 2 << endl;
        cout << l + 2 << " to " << r - 2 << endl;
        cout << r - 4 << " to " << l + 2 << endl;
        cout << l - 1 << " to " << r - 4 << endl;
        cout << r - 1 << " to " << l - 1 << endl;
    } else if (r - l + 1 == 12) {
        cout << r - 2 << " to " << l - 2 << endl;
        cout << r - 5 << " to " << r - 2 << endl;
        cout << l + 1 << " to " << r - 5 << endl;
        cout << r - 6 << " to " << l + 1 << endl;
        cout << l - 1 << " to " << r - 6 << endl;
        cout << r - 1 << " to " << l - 1 << endl;
    } else if (r - l + 1 == 14) {
        cout << l + 7 << " to " << l - 2 << endl;
        cout << l + 4 << " to " << l + 7 << endl;
        cout << r - 2 << " to " << l + 4 << endl;
        cout << l + 2 << " to " << r - 2 << endl;
        cout << r - 5 << " to " << l + 2 << endl;
        cout << l - 1 << " to " << r - 5 << endl;
        cout << r - 1 << " to " << l - 1 << endl;
    } else {
        cout << r - 2 << " to " << l - 2 << endl;
        cout << l + 2 << " to " << r - 2 << endl;
        work(l + 4, r - 4);
        cout << l - 1 << " to " << r - 5 << endl;
        cout << r - 1 << " to " << l - 1 << endl;
    }
    return;
}
/*====================*/
void Solve(int n) {
    if (n == 3) {
        cout << "2 to -1\n" << "5 to 2\n" << "3 to -3\n";
    } else {
        work(1, 2 * n);
    }
    return;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...