📌  相关文章
📜  通过交换满足给定条件的对对前 N 个自然数的排列进行排序

📅  最后修改于: 2022-05-13 01:56:09.960000             🧑  作者: Mango

通过交换满足给定条件的对对前 N 个自然数的排列进行排序

给定一个大小为N的数组p[]表示前N个自然数的排列,其中N是偶数,任务是通过获取一对索引a、b并交换p[a]p[ b]在每个操作中,其中2 * |a – b| ≥N 。打印在每个操作中交换的索引对。

例子:

解决方法:按照以下步骤解决问题:

  • 创建一个数组posOfCurrNum[]来存储p[]中存在的数字的位置。
  • 使用变量i[1, N]范围内迭代并将posOfCurrNum[p[i]]设置为i
  • 声明一个对ans的向量来存储为对给定数组p[]进行排序而执行的交换。
  • 使用变量i[1, N]范围内迭代
    • 如果p[i]等于i ,那么这意味着当前数字i已经出现在正确的位置。所以,继续下一次迭代。
    • 使用posOfCurrNum[i]初始化变量j以存储数字i的当前位置。
    • 现在,出现了4种情况:
      • 情况 1:如果|i – j| * 2大于n ,然后,交换(i,j)并将这对存储在ans中。
      • 情况 2:如果n/2小于或等于i – 1 ,则swap(i, 1) → swap(1, j) → swap(i, 1)并将这些对存储在ans中。
      • 情况 3:如果n/2小于或等于n – j ,则swap(i, n) → swap(j, n) → swap(i, n)并将这些对存储在ans中。
      • 情况 4:如果n/2小于j -1并且n/2小于或等于n – i ,则swap(i, n) → swap(n, 1) → swap(1, j) → swap (1, n) → swap(i, n)并将这些对存储在ans中。
  • 打印向量的大小ans
  • 遍历对向量ans并打印每一对。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to swap integers
// in an operation
void Swap(int x, int y, int p[],
          int posOfCurrNum[])
{
    swap(posOfCurrNum[p[x]],
         posOfCurrNum[p[y]]);
 
    swap(p[x], p[y]);
}
 
// Function to sort permutation
// using given operations
void sortArray(int p[], int n)
{
    // Store the position of the
    // array elements
    int posOfCurrNum[n + 1];
    for (int i = 1; i <= n; i++) {
        posOfCurrNum[p[i]] = i;
    }
 
    // Store the result
    vector > ans;
 
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
 
        // If current number is already
        // present at the right position
        if (p[i] == i) {
            continue;
        }
 
        // Store the current position of
        // the number 'i'
        int j = posOfCurrNum[i];
 
        // Case 1: If both the indices
        // satisfies the given condition
        if (abs(i - j) * 2 >= n) {
 
            Swap(i, j, p, posOfCurrNum);
 
            ans.push_back({ i, j });
        }
 
        // Case 2: If the current number
        // 'i' is present at right side
        // of half of the given array
        else if (n / 2 <= i - 1) {
 
            Swap(1, i, p, posOfCurrNum);
            ans.push_back({ i, 1 });
 
            Swap(1, j, p, posOfCurrNum);
            ans.push_back({ 1, j });
 
            Swap(i, 1, p, posOfCurrNum);
            ans.push_back({ i, 1 });
        }
 
        // Case 3: If the position of the
        // current number 'i' is left side
        // of half of the given array
        else if (n - j >= n / 2) {
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
 
            Swap(j, n, p, posOfCurrNum);
            ans.push_back({ j, n });
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
        }
 
        // Case 4: For all other cases
        else {
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
 
            Swap(n, 1, p, posOfCurrNum);
            ans.push_back({ n, 1 });
 
            Swap(1, j, p, posOfCurrNum);
            ans.push_back({ 1, j });
 
            Swap(1, n, p, posOfCurrNum);
            ans.push_back({ 1, n });
 
            Swap(i, n, p, posOfCurrNum);
            ans.push_back({ i, n });
        }
    }
 
    // Print the number of operations
    cout << ans.size() << '\n';
 
    // Print the steps
    for (auto p : ans)
        cout << p.first << " "
             << p.second << '\n';
}
 
// Driver Code
int main()
{
 
    // Given Input
    int n = 6;
 
    // Append 0 to consider
    // 1-based indexing
    int p[] = { 0, 2, 5, 3, 1, 4, 6 };
 
    // Function Call
    sortArray(p, n);
 
    return 0;
}


Java
// Java program for the above approach
import java.lang.*;
import java.util.*;
 
class pair
{
  int first, second;
  pair(int first, int second)
  {
    this.first = first;
    this.second = second;
  }
}
class GFG
{
   
  // Function to swap integers
  // in an operation
  static void Swap(int x, int y, int p[],
                   int posOfCurrNum[])
  {
    int t1 = posOfCurrNum[p[x]];
    posOfCurrNum[p[x]] = posOfCurrNum[p[y]];
    posOfCurrNum[p[y]] = t1;
 
    int t2 = p[x];
    p[x] = p[y];
    p[y] = t2;
  }
 
  // Function to sort permutation
  // using given operations
  static void sortArray(int p[], int n)
  {
    // Store the position of the
    // array elements
    int[] posOfCurrNum = new int[n + 1];
    for (int i = 1; i <= n; i++) {
      posOfCurrNum[p[i]] = i;
    }
 
    // Store the result
    ArrayList ans=new ArrayList<>();
 
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
 
      // If current number is already
      // present at the right position
      if (p[i] == i) {
        continue;
      }
 
      // Store the current position of
      // the number 'i'
      int j = posOfCurrNum[i];
 
      // Case 1: If both the indices
      // satisfies the given condition
      if (Math.abs(i - j) * 2 >= n) {
 
        Swap(i, j, p, posOfCurrNum);
 
        ans.add(new pair( i, j ));
      }
 
      // Case 2: If the current number
      // 'i' is present at right side
      // of half of the given array
      else if (n / 2 <= i - 1) {
 
        Swap(1, i, p, posOfCurrNum);
        ans.add(new pair( i, 1 ));
 
        Swap(1, j, p, posOfCurrNum);
        ans.add(new pair( 1, j ));
 
        Swap(i, 1, p, posOfCurrNum);
        ans.add(new pair( i, 1 ));
      }
 
      // Case 3: If the position of the
      // current number 'i' is left side
      // of half of the given array
      else if (n - j >= n / 2) {
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
 
        Swap(j, n, p, posOfCurrNum);
        ans.add(new pair( j, n ));
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
      }
 
      // Case 4: For all other cases
      else {
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
 
        Swap(n, 1, p, posOfCurrNum);
        ans.add(new pair( n, 1 ));
 
        Swap(1, j, p, posOfCurrNum);
        ans.add(new pair( 1, j ));
 
        Swap(1, n, p, posOfCurrNum);
        ans.add(new pair( 1, n ));
 
        Swap(i, n, p, posOfCurrNum);
        ans.add(new pair( i, n ));
      }
    }
 
    // Print the number of operations
    System.out.println(ans.size());
 
    // Print the steps
    for (pair pp : ans)
      System.out.println(pp.first+" "+pp.second);
  }
   
  // Driver code
  public static void main(String[] args)
  {
 
    // Given Input
    int n = 6;
 
    // Append 0 to consider
    // 1-based indexing
    int p[] = { 0, 2, 5, 3, 1, 4, 6 };
 
    // Function Call
    sortArray(p, n);
 
  }
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
 
# Function to swap integers
# in an operation
def Swap(x, y, p, posOfCurrNum):
     
    posOfCurrNum[p[x]], posOfCurrNum[p[y]] = posOfCurrNum[p[y]], posOfCurrNum[p[x]]
 
    p[x], p[y] = p[y], p[x]
    return p, posOfCurrNum
 
# Function to sort permutation
# using given operations
def sortArray(p, n):
     
    # Store the position of the
    # array elements
    posOfCurrNum = [0] * (n + 1)
    for i in range(1, n + 1):
        posOfCurrNum[p[i]] = i
 
    # Store the result
    ans = []
 
    # Traverse the given array, p[]
    for i in range(1, n + 1):
         
        # If current number is already
        # present at the right position
        if (p[i] == i):
            continue
 
        # Store the current position of
        # the number 'i'
        j = posOfCurrNum[i]
 
        # Case 1: If both the indices
        # satisfies the given condition
        if (abs(i - j) * 2 >= n):
            p, posOfCurrNum = Swap(i, j, p, posOfCurrNum)
 
            ans.append([i, j])
             
        # Case 2: If the current number
        # 'i' is present at right side
        # of half of the given array
        elif (n // 2 <= i - 1):
            p, posOfCurrNum = Swap(1, i, p, posOfCurrNum)
            ans.append([i, 1])
 
            p, posOfCurrNum = Swap(1, j, p, posOfCurrNum)
            ans.append([1, j])
 
            p, posOfCurrNum = Swap(i, 1, p, posOfCurrNum)
            ans.append([i, 1])
 
        # Case 3: If the position of the
        # current number 'i' is left side
        # of half of the given array
        elif (n - j >= n // 2):
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
            p, posOfCurrNum = Swap(j, n, p, posOfCurrNum)
            ans.append([j, n])
 
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
             
        # Case 4: For all other cases
        else:
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
            p, posOfCurrNum = Swap(n, 1, p, posOfCurrNum)
            ans.append([n, 1])
 
            p, posOfCurrNum = Swap(1, j, p, posOfCurrNum)
            ans.append([1, j])
 
            p, posOfCurrNum = Swap(1, n, p, posOfCurrNum)
            ans.append([1, n])
 
            p, posOfCurrNum = Swap(i, n, p, posOfCurrNum)
            ans.append([i, n])
 
    # Print the number of operations
    print(len(ans))
 
    # Print the steps
    for p in ans:
        print(p[0], p[1])
 
# Driver Code
if __name__ == '__main__':
 
    # Given Input
    n = 6
 
    # Append 0 to consider
    # 1-based indexing
    p = [ 0, 2, 5, 3, 1, 4, 6 ]
 
    # Function Call
    sortArray(p, n)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
  // Function to swap integers
  // in an operation
  static void Swap(int x, int y, int[] p,
                   int[] posOfCurrNum)
  {
    int t1 = posOfCurrNum[p[x]];
    posOfCurrNum[p[x]] = posOfCurrNum[p[y]];
    posOfCurrNum[p[y]] = t1;
  
    int t2 = p[x];
    p[x] = p[y];
    p[y] = t2;
  }
  
  // Function to sort permutation
  // using given operations
  static void sortArray(int[] p, int n)
  {
    // Store the position of the
    // array elements
    int[] posOfCurrNum = new int[n + 1];
    for (int i = 1; i <= n; i++) {
      posOfCurrNum[p[i]] = i;
    }
  
    // Store the result
    List> ans = new List>();
  
    // Traverse the given array, p[]
    for (int i = 1; i <= n; i++) {
  
      // If current number is already
      // present at the right position
      if (p[i] == i) {
        continue;
      }
  
      // Store the current position of
      // the number 'i'
      int j = posOfCurrNum[i];
  
      // Case 1: If both the indices
      // satisfies the given condition
      if (Math.Abs(i - j) * 2 >= n) {
  
        Swap(i, j, p, posOfCurrNum);
  
        ans.Add(new Tuple(i, j));
      }
  
      // Case 2: If the current number
      // 'i' is present at right side
      // of half of the given array
      else if (n / 2 <= i - 1) {
  
        Swap(1, i, p, posOfCurrNum);
        ans.Add(new Tuple(i, 1));
  
        Swap(1, j, p, posOfCurrNum);
        ans.Add(new Tuple(1, j));
  
        Swap(i, 1, p, posOfCurrNum);
        ans.Add(new Tuple(i, 1));
      }
  
      // Case 3: If the position of the
      // current number 'i' is left side
      // of half of the given array
      else if (n - j >= n / 2) {
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple(i, n));
  
        Swap(j, n, p, posOfCurrNum);
        ans.Add(new Tuple(j, n));
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple(i, n));
      }
  
      // Case 4: For all other cases
      else {
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple(i, n));
  
        Swap(n, 1, p, posOfCurrNum);
        ans.Add(new Tuple(n, 1));
  
        Swap(1, j, p, posOfCurrNum);
        ans.Add(new Tuple(1, 4));
  
        Swap(1, n, p, posOfCurrNum);
        ans.Add(new Tuple(1, 6));
  
        Swap(i, n, p, posOfCurrNum);
        ans.Add(new Tuple(i, n));
      }
    }
  
    // Print the number of operations
    Console.WriteLine(ans.Count);
  
    // Print the steps
    foreach(Tuple pp in ans)
      Console.WriteLine(pp.Item1+" "+pp.Item2);
  }
     
 // Driver code
  static void Main()
  {
     
    // Given Input
    int n = 6;
  
    // Append 0 to consider
    // 1-based indexing
    int[] p = { 0, 2, 5, 3, 1, 4, 6 };
  
    // Function Call
    sortArray(p, n);
  }
}
 
// This code is contributed by mukesh07.


Javascript


输出:
9
1 4
2 6
6 1
1 4
1 6
2 6
4 1
1 5
4 1

时间复杂度: O(N)
辅助空间: O(N)