暑假集训 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这样的序列,按照我的想法输出的应该是第一个与第一个交换,,,,思维死角

原文地址:https://www.cnblogs.com/smilesundream/p/5661499.html