题意:给定一个序列,现有一种操作:两个数的位置互换。问最多操作一次,序列 [元素位置i] 与 [元素Ai] 相等的最多个数?
根据题意,最多个数为 :
【操作之前[元素位置i] 与 [元素Ai] 相等的个数】 + 【调换两个 [元素位置i] 与 [元素Ai] 不相等 的元素 使某个 [元素位置i] 与 [元素Ai] 相等的个数】。
举个例子:
0 1 2 4 3
这个序列,调换后面两个元素,正好使每个 [元素位置i] 与 [元素Ai] 相等。
也就是说,调换的时候,不用考虑 [元素位置i] 与 [元素Ai] 相等 的元素了。
直接考虑 [元素位置i] 与 [元素Ai] 不相等 的元素中,能否调换一次之后使 一个 或 两个元素[元素位置i] 与 [元素Ai] 相等。
调换后若有1个元素 [元素位置i] 与 [元素Ai] 相等
那么最多个数 = 【操作之前[元素位置i] 与 [元素Ai] 相等的个数】 + 1,若有2个元素则 + 2。
接下来就可以根据这个用map来解决这个问题了。
#include <stdio.h> #include <map> using namespace std; int main() { int n, ans; while(~scanf("%d", &n)) { map<int, int> mm; ans = 0; for(int i = 0; i < n; i++) { int temp; scanf("%d", &temp); if(temp == i) { ++ans; } else { mm[i] = temp; } } map<int, int>::iterator it = mm.begin(); for(;it != mm.end();it++) { if(mm.find((*it).second) != mm.end() && mm[(*it).second] == (*it).first) { ++ans; break; } } if(ans != n) ++ans; printf("%d\n", ans); } return 0; }
Codeforces 347B - Fixed Points
时间: 2024-10-17 15:09:32