ZOJ 1201. Inversion

题目描述

Let { A1,A2,…,An } be a permutation of the set{ 1,2,…, n}. If i < j and Ai > Aj then the pair (Ai,Aj) is called an “inversion” of the permutation. For example, the permutation {3, 1, 4, 2} has three inversions: (3,1), (3,2) and (4,2).
The inversion table B1,B2,…,Bn of the permutation { A1,A2,…,An } is obtained by letting Bj be the number of elements to the left of j that are greater than j. (In other words, Bj is the number of inversions whose second component is j.) For example, the permutation:
{ 5,9,1,8,2,6,4,7,3 }
has the inversion table
2 3 6 4 0 2 2 1 0
since there are 2 numbers, 5 and 9, to the left of 1; 3 numbers, 5, 9 and 8, to the left of 2; etc.
Perhaps the most important fact about inversions is Marshall Hall’s observation that an inversion table uniquely determines the corresponding permutation. So your task is to convert a permutation to its inversion table, or vise versa, to convert from an inversion table to the corresponding permutation.

Input:

The input consists of several test cases. Each test case contains two lines.
The first line contains a single integer N ( 1 <= N <= 50) which indicates the number of elements in the permutation/invertion table.
The second line begins with a single charactor either ‘P’, meaning that the next N integers form a permutation, or ‘I’, meaning that the next N integers form an inversion table.
Following are N integers, separated by spaces. The input is terminated by a line contains N=0.

Output:

For each case of the input output a line of intergers, seperated by a single space (no space at the end of the line). If the input is a permutation, your output will be the corresponding inversion table; if the input is an inversion table, your output will be the corresponding permutation.

Sample Input:

9
P 5 9 1 8 2 6 4 7 3
9
I 2 3 6 4 0 2 2 1 0
0

Sample Output:

2 3 6 4 0 2 2 1 0
5 9 1 8 2 6 4 7 3


核心思路
  • permutation -> inversion:
    因为n的数据范围不大,所以可以用朴素版的双指针算法。
    双指针 : i 指向目标数字 ,j 从头向后扫描寻找比i要大的数,遇到i 就回滚,寻找一个数 i+1;

  • inversion -> permutation:
    类似哈希表的方法。


附带本人提交情况

提交通过的时间仅需4毫秒
提交运行时间,4毫秒。


C++代码
#include<iostream> 
#include<cstring> 
using namespace std;

const int N = 60;
int a[N],t[N];
int n;
char c;

void permutation_to_inversion()
{
	for(int i=1;i<=n;i++)          // 双指针 :i 指向目标数字 ,j 从头向后扫描寻找比i要大的数,遇到i 就回滚,寻找一个数 i+1; 
	{  int j=1;
		while(j<=n)
		{
   	 	if(a[j]==i)break;
			if(a[j]>i)
			{
				t[i]++; j++;
        	}
        	else j++; 
   	 
       }
    }
}

void inversion_to_permutation()
{
	int i,j,count,k;
   for(j=1; j<=n; j++)
   {
       count = 0;
    
       for(i=1; i<=n && count<a[j]; i++)
       {                                                         // 扫描寻找 符合的位置
           if( t[i]==0 )
               count++;
       }
      
       if( t[i] != 0)     // 位置发生了冲突。
           for(k=i+1; k<=n; k++)
               if( t[k] == 0 ) 
               {
                   i = k;
                   break;
               }
       t[i] = j;      
   }
  
}

int main()
{
	ios::sync_with_stdio(false);
    cin.tie(nullptr);
   while(cin>>n&&n!=0)
	{

		cin>>c;
	
	    memset(a,0,sizeof(a));
	    memset(t,0,sizeof(t));
	    
   	for(int i=1;i<=n;i++) cin>>a[i];
		
   	if(c=='P') permutation_to_inversion();
       else inversion_to_permutation();
  		
   	for(int i=1;i<=n;i++) 
   	{   if(i!=1)cout<<" ";
   		cout<<t[i];
       }
       cout<<"\n";
   
   }
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅小柏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值