• Codeforces 28B. pSort (并查集)


    One day n cells of some array decided to play the following game. Initially each cell contains a number which is equal to it's ordinal number (starting from 1). Also each cell determined it's favourite number. On it's move i-th cell can exchange it's value with the value of some other j-th cell, if |i - j| = di, where di is a favourite number of i-th cell. Cells make moves in any order, the number of moves is unlimited.

    The favourite number of each cell will be given to you. You will also be given a permutation of numbers from 1 to n. You are to determine whether the game could move to this state.

    Input

    The first line contains positive integer n (1 ≤ n ≤ 100) — the number of cells in the array. The second line contains n distinct integers from 1 to n — permutation. The last line contains n integers from 1 to n — favourite numbers of the cells.

    Output

    If the given state is reachable in the described game, output YES, otherwise NO.

    Example

    Input
    5
    5 4 3 2 1
    1 1 1 1 1
    Output
    YES
    Input
    7
    4 3 5 1 2 7 6
    4 6 6 1 6 6 1
    Output
    NO
    Input
    7
    4 2 5 1 3 7 6
    4 6 6 1 6 6 1
    Output
    YES

    分析:
    需要判断每个数是否能移动到它所指定的位置上,
    这里两个数经过一些中间量进行位置交换的时候,不影响中间量的位置。
    所以可以独立的判断每次交换。
    这里我们把能够互相交换的序号放在同一个集合里,运用并查集来判断每个数能否移动到指定位置
    代码如下:
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int pre[110];
    int n;
    int id[110];
    int val[110];
    int Find(int x)
    {
        int h=x,tmp;
        while(pre[x]!=x)
        x=pre[x];
        while(h!=x)
        {
            tmp=pre[h];
            pre[h]=x;
            h=tmp;
        }
        return x;
    }
    void init()
    {
        for(int i=1;i<=n;i++)
        pre[i]=i;
    }
    void join(int x,int y)
    {
        int p=Find(x);
        int q=Find(y);
        if(p!=q)
        pre[p]=q;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        init();
        int x,flag;
        flag=1;
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            id[x]=i;
        }
        for(int i=1;i<=n;i++)
        cin>>val[i];
        for(int i=1;i<=n;i++)
        {
          if(i-val[i]>=1)
          join(i,i-val[i]);
          if(i+val[i]<=n)
          join(i,i+val[i]);
        }
        for(int i=1;i<=n;i++)
        {
          if(Find(id[i])!=Find(i))
          {
              flag=0;
              break;
          }
        }
        if(flag==1)puts("YES");
        else puts("NO");
        return 0;
    }
  • 相关阅读:
    编程题:数组中出现超数组长度一半的数字
    编程题:两数之和&数组中相加为0的三元数组
    编程题:最小矩阵路径
    编程题:斐波那契数列青蛙跳台阶
    向excel文件中写内容
    Java:使用jxl读取excel文件内容
    索尼1a dac插电脑用什么驱动。在哪下载,求助
    idea启动项目报端口号冲突或被占用
    两分钟解决IntelliJ IDEA中文乱码问题
    IntelliJ IDEA以不同格式导出数据库的数据
  • 原文地址:https://www.cnblogs.com/a249189046/p/8447137.html
Copyright © 2020-2023  润新知