codechef Ambiguous Permutations 题解

Some programming contest problems are really tricky: not only do they
require a different output format from what you might have expected, but
also the sample output does not show the difference. For an example,
let us look at permutations.
permutation of the integers 1 to n is an
ordering of
these integers. So the natural way to represent a permutation is
to list the integers in this order. With n = 5, a
permutation might look like 2, 3, 4, 5, 1. 
However, there is another possibility of representing a permutation:
You create a list of numbers where the i-th number is the
position of the integer i in the permutation.
Let us call this second
possibility an inverse permutation. The inverse permutation
for the sequence above is 5, 1, 2, 3, 4.

An ambiguous permutation is a permutation which cannot be
distinguished from its inverse permutation. The permutation 1, 4, 3, 2
for example is ambiguous, because its inverse permutation is the same.
To get rid of such annoying sample test cases, you have to write a
program which detects if a given permutation is ambiguous or not.

Sample Input

4
1 4 3 2
5
2 3 4 5 1
1
1
0

Sample Output

ambiguous
not ambiguous
ambiguous

输入数据也是超大的。最大单列有100000个整数

所以这次使用getchar和fputs来处理数据,速度还不错。

#pragma once
#include <stdio.h>

int scanInt()
{
	register int res = 0, next = 0;
	while ((next = getchar()) >= '0' && next <= '9')
	{
		res = (res<<3) + (res<<1) + next - '0';
	}
	return res;
}

int AmbiguousPermutations()
{
	char *ambiguous = "ambiguous\n";
	char *nonAmbiguous = "not ambiguous\n";
	int n = 0;
	while ((n = scanInt()) != 0)
	{
		int *A = new int[n+1];
		int *B = new int[n+1];
		for (int i = 1; i <= n; i++)
		{
			A[i] = scanInt();
			B[A[i]] = i;
		}
		bool isAmbiguous = true;
		for (int i = 1; i <= n; i++)
		{
			if (A[i] != B[i])
			{
				isAmbiguous = false;
				break;
			}
		}
		if (isAmbiguous) fputs(ambiguous, stdout);
		else fputs(nonAmbiguous, stdout);
		delete [] A;
		delete [] B;
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值