CF634A Island Puzzle 题解

 题目描述

A remote island chain contains n islands, labeled 1 through n . Bidirectional bridges connect the islands to form a simple cycle — a bridge connects islands 1 and 2 , islands 2 and 3 , and so on, and additionally a bridge connects islands n and 1 . The center of each island contains an identical pedestal, and all but one of the islands has a fragile, uniquely colored statue currently held on the pedestal. The remaining island holds only an empty pedestal.

The islanders want to rearrange the statues in a new order. To do this, they repeat the following process: First, they choose an island directly adjacent to the island containing an empty pedestal. Then, they painstakingly carry the statue on this island across the adjoining bridge and place it on the empty pedestal.

Determine if it is possible for the islanders to arrange the statues in the desired order.

 输入格式

The first line contains a single integer n$ 2<=n<=200000 $ ) — the total number of islands.

The second line contains n space-separated integers $ a_{i} $ ( $ 0<=a_{i}<=n-1 $ ) — the statue currently placed on the i -th island. If $ a_{i}=0 $ , then the island has no statue. It is guaranteed that the $ a_{i} $ are distinct.

The third line contains n space-separated integers $ b_{i} $$ 0<=b_{i}<=n-1 $ ) — the desired statues of the i -th island. Once again, $ b_{i}=0 $ indicates the island desires no statue. It is guaranteed that the $ b_{i} $ are distinct.

 输出格式

Print "YES" (without quotes) if the rearrangement can be done in the existing network, and "NO" otherwise.

 样例 #1

样例输入 #1

3
1 0 2
2 0 1

样例输出 #1

YES

 样例 #2

样例输入 #2

2
1 0
0 1

样例输出 #2

YES

 样例 #3

样例输入 #3

4
1 2 3 0
0 3 2 1

样例输出 #3

NO

 提示

In the first sample, the islanders can first move statue 1 from island 1 to island 2 , then move statue 2 from island 3 to island 1 , and finally move statue 1 from island 2 to island 3 .

In the second sample, the islanders can simply move statue 1 from island 1 to island 2 .

In the third sample, no sequence of movements results in the desired position.

题目传送门(题目源自洛谷)

我看现有的两篇题解都是一笔带过,说的有点模糊(反正我没看懂),于是来写篇题解。

 题意

这道题的题意我就不多说了,自己右键机翻一下也勉强能看懂。

有 $n$ 个岛屿形成一个环,每个岛屿上有一个底座可以放雕像,后来出了一些情况导致这些雕像的顺序被打乱了,给出现在每个岛屿上放着的雕像的编号以及先前的顺序,问你是否可以将雕像放回原位。

上面这段文字可以结合样例理解。(输入的第二个数组是原来的排列顺序

 思路

再把题目“化简”一下就是:给出环形数组 $A$ 以及目标数组,问是否可以让数组 $A$ 中的元素通过向相邻位置移动变为目标数组。

到这里题目就已经很简单了,思考下样例就能想明白,比如样例一:

$A$ 数组:$102$$012$$210$$201$

目标数组:$201$

显然我们可以枚举通过移动产生的所有不同的 $A$ 数组,如果有一种情况与目标数组相同就输出 YES,否则如果枚举完所有情况还没出现与目标数组相同的情况,输出 $NO$

再举个例子,看样例三:

$A$ 数组:$1230$$0321$$2310$$3120$$1230$

目标数组:$0321$

这个样例可以枚举出很多情况,这里我就不一一写出,但很容易发现如果我们把所有 $0$ 都去掉,就会出来一堆重复的情况,这时就可以想到:要是把所有 $0$ 都去除再枚举情况,效率会高很多

另外,因为数组中的元素只能向相邻处平移,要不是因为这数组是个环,两个数组去 $0$ 后如果还不相同,直接输出 $NO$ 就完事了。但很可惜它就是个,所以我们要从环的性质来入手:首尾相连,也就是说数组的第一个元素可以移动到末尾,末尾的元素同样可以移动到开头,比如 $1234$ 可以变成 $2341$ 或是 $4123$

顺着这条思路去想,那所谓枚举所有情况不就是不断把第一个元素移到末尾吗?这时问题就已经解决了,可能有人会问为什么不考虑把末尾的元素移动到开头的情况,其实只要自己出几个样例模拟一下就明白了,其实它们枚举出的情况是相同的。

这样想来,一共就只有 $n$ 种情况了。

 完整代码

#include<bits/stdc++.h>
using namespace std;
//不用在意我的快读...
inline int read(){
    int x;char ch;
    while(true){
        ch=getchar();
        if(ch>='0'&&ch<='9') break;
    }x=ch-'0';
    while(true){
        ch=getchar();
        if(ch<'0'||ch>'9') break;
        x=x*10+ch-'0';
    }return x;
}
int a[200002],aim[200002];
//same函数判断两个数组是否相同
bool same(int n){
    for(int i=1;i<=n;i++) 
        if(a[i]!=aim[i]) return 0;
    return 1;
}
int main()
{
    int n;n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        if(!a[i]) i--,n--;
        //这里的n--很重要,否则输入时就会RE
    }
    for(int i=1;i<=n;i++){
        aim[i]=read();
        if(!aim[i]) i--;
        //如果a[i]==0,就i--,下一次循环时
        //下标i又会加回来,这样就不会在数组中加入0
    }
    for(int i=1;i<=n;i++){
        if(same(n)){
            printf("YES");
            return 0;
        }
        //把开头元素放到末尾
        a[n+1]=a[1];
        for(int j=1;j<=n;j++) a[j]=a[j+1];
    }
    printf("NO");
    return 0;
}

顺便推广一下我的洛谷博客:charlotte_TYQのブログ 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值