百度之星 1003 鸽子(思维+模拟)

链接

题意:

就是给你n个数1-n,然后m次交换操作,k是故障的机器,问你最少不执行多少次交换操作,似的最后故障的机器落到\(j\)上。

分析:

首先我们手模下样例:

5 5 1
原数组:1 2 3 4 5
3 5
操作后:1 2 5 4 3
2 1
操作后:2 1 5 4 3
4 1
操作后:4 1 5 2 3
3 1
操作后:5 1 4 2 3
3 1
操作后:4 1 5 2 3

我们看操作的位置可以看出并不能看出什么,哈哈哈
然后我们可以看里面交换的数值。

原数组:1 2 3 4 5
3 5  -----相当于交换 3  5 
操作后:1 2 5 4 3
2 1	------相当于交换1 2
操作后:2 1 5 4 3
4 1 -------相当于交换2 4
操作后:4 1 5 2 3
3 1 --------相当于交换 4 5
操作后:5 1 4 2 3
3 1 --------相当于交换 4 5
操作后:4 1 5 2 3

然后我们发现要是想 将k移动到位置1上去,其实就是将 数值4和1交换。
然后我们就想到只能是从前往后的最短路径,原k位置为0。找到去其他地方的最短路径即可。

void solve()
{
       n=read;m=read;k=read;
       for(int i=1;i<=n;i++){
           a[i]=i;
           b[i]=1e9+7;
       }
       b[k]=0;
       
    for(int i=1;i<=m;i++){
        ll x,y;
        x=read;y=read;
        swap(a[x],a[y]);        
        x=a[x],y=a[y];
        if(b[x]<b[y]){
            b[y]=min(b[y],b[x]+1);
        }else {
            b[x]=min(b[y]+1,b[x]);
        }
    }
    for(int i=1;i<=n;i++){
        if(b[a[i]]>=1e9+7) printf("-1");
        else printf("%lld",b[a[i]]);
        if(i==n){
                puts("");    
        }else {
            printf(" ");
        }
    } 
}
posted @ 2021-07-31 20:00  `KingZhang`  阅读(265)  评论(0)    收藏  举报