zoukankan      html  css  js  c++  java
  • 暑假集训 div1 B Derangement 交换数字 思维死角

    B. Derangement
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    A permutation of n numbers is a sequence of integers from 1 to n where each number is occurred exactly once. If a permutation p1, p2, ..., pn has an index i such that pi = i, this index is called a fixed point.

    A derangement is a permutation without any fixed points.

    Let's denote the operation swap(a, b) as swapping elements on positions a and b.

    For the given permutation find the minimal number of swap operations needed to turn it into derangement.

    Input

    The first line contains an integer n (2 ≤ n ≤ 200000) — the number of elements in a permutation.

    The second line contains the elements of the permutation — n distinct integers from 1 to n.

    Output

    In the first line output a single integer k — the minimal number of swap operations needed to transform the permutation into derangement.

    In each of the next k lines output two integers ai and bi (1 ≤ ai, bi ≤ n) — the arguments ofswap operations.

    If there are multiple possible solutions, output any of them.

    Examples
    input
    6 6 2 4 3 5 1
    output
    1 2 5
    题意:给你1-n数字组成的一个序列,你可以进行a,b操作把a,b位置上的数字交换位置,问最少进行多少次交换
    才使得整个序列中不存在第i个位置的数字为i这样情况。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <set>
    #include <cmath>
    using namespace std;
    const double eps=1e-10;
    
    int a[200006][4];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            int cnt=0,last=0;
            for(int i=1;i<=n;i++)
            {
                int u;
                scanf("%d",&u);
                if(u==i)
                {
                   cnt++;
                  if(last!=0)
                  {
                   a[cnt/2][0]=last;
                   a[cnt/2][1]=u;
                   last=0;
                  }
                  else last=u;
                }
            }
            if(cnt%2!=0) {
                a[cnt/2+1][0]=last;
                if(last!=1) a[cnt/2+1][1]=1;
                else a[cnt/2+1][1]=2;
            }
            printf("%d
    ",cnt/2+cnt%2);
            for(int i=1;i<=cnt/2+cnt%2;i++)
                printf("%d %d
    ",a[i][0],a[i][1]);
        }
        return 0;
    }
    

     分析:其实这个问题其他的都分析很好,就错了一个地方,就是当还剩余最后一个数字无法进行交换时,这时

    很显然我们只需要把他与其他的数字中任意一个进行下交换,所以我想的就是与第一个数字交换,,,,,但是,没有

    考虑到1,3,2这样的序列,按照我的想法输出的应该是第一个与第一个交换,,,,思维死角

  • 相关阅读:
    Scrapy
    关于函数名称和库函数名称冲突的故事
    Hibernate的一级缓存
    spring-mvc 与 openid4java
    openid4java 使用记录[转载]
    Linux定时任务Crontab详解_定时备份
    Spring的线程池ThreadPoolTaskExecutor使用案例
    BZOJ4275 : [ONTAK2015]Badania naukowe
    BZOJ4137 : [FJOI2015]火星商店问题
    BZOJ2832 : 宅男小C
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5661499.html
Copyright © 2011-2022 走看看