Round #201 (Div.2) B. Fixed Points

来源:互联网 发布:文字数据分析 编辑:程序博客网 时间:2024/05/04 19:40
B. Fixed Points
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A permutation of length n is an integer sequence such that each integer from 0 to(n - 1) appears exactly once in it. For example, sequence[0, 2, 1] is a permutation of length 3 while both [0, 2, 2] and [1, 2, 3] are not.

A fixed point of a function is a point that is mapped to itself by the function. A permutation can be regarded as a bijective function. We'll get a definition of a fixed point in a permutation. An integeri is a fixed point of permutation a0, a1, ..., an - 1 if and only ifai = i. For example, permutation[0, 2, 1] has 1 fixed point and permutation[0, 1, 2] has 3 fixed points.

You are given permutation a. You are allowed to swap two elements of the permutation at most once. Your task is to maximize the number of fixed points in the resulting permutation. Note that you are allowed to make at most one swap operation.

Input

The first line contains a single integer n(1 ≤ n ≤ 105). The second line containsn integers a0, a1, ..., an - 1 — the given permutation.

Output

Print a single integer — the maximum possible number of fixed points in the permutation after at most one swap operation.

Sample test(s)
Input
50 1 3 4 2
Output
3

————————————————————CF的分割线————————————————————

思路:交换的两个数仅一次,使得数组中和其下标相等的数字最多。两个for循环扫会超时,所以只能扫一次。另开一个vis数组,以和下标不一样的数字为下标储存这个数字的下标,即vis[a[i]] = i, 这样在扫一次的时候只要判断vis[i]是否等于a[i],就可以知道交换这两个数字能不能增加两个fixed points。既然记录了错位的数字错在哪个下标,那么扫一次的时候直接利用这个下标去看数字就行了。

PS:还要讨论一下所有数字都是正确的情况。

代码如下:

/*ID: j.sure.1PROG: LANG: C++*//****************************************/#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <stack>#include <queue>#include <vector>#include <map>#include <string>#include <iostream>using namespace std;/****************************************/const int N = 100005;int a[N], vis[N];int main(){//freopen(".in", "r", stdin);//freopen(".out", "w", stdout);int n, cnt = 0, ans = 0;bool ok = false;scanf("%d", &n);for(int i = 0; i < n; i++) {scanf("%d", &a[i]);if(a[i] != i) {ok = true;vis[a[i]] = i;}elseans++;}if(!ok)printf("%d\n", ans);else {bool flag = false;for(int i = 0; i < n; i++) {if(a[i] != i) {if(vis[i] == a[i]) {flag = true;break;}}}if(flag)printf("%d\n", ans+2);elseprintf("%d\n", ans+1);}return 0;}


0 0
原创粉丝点击