Gym 100971B Derangement
要求改换序列,使得没有位置是a[i] == i成立。输出最小要换的步数
首先把a[i] == i的位置记录起来,然后两两互相换就可以了。
对于是奇数的情况,和它前一个换或者后一个换就可以,(注意前一个越界或者后一个越界)
这样是不会重复的,因为本来i是a[i] == i的话,换了一个,是不会使得他们两个a[i] == i的
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 200000 + 20; int a[maxn]; vector<int>pos; void work () { int n; cin>>n; for (int i = 1; i <= n; ++i) scanf ("%d",&a[i]); for (int i = 1; i <= n; ++i) { if (a[i] == i) pos.push_back(i); } printf ("%d\n",pos.size() / 2 + (pos.size() & 1)); if (pos.size() & 1) { for (int i = 0; i < pos.size() - 1; i += 2) { printf ("%d %d\n",pos[i],pos[i + 1]); } int t1 = pos[pos.size() - 1] - 1; int t2 = pos[pos.size() - 1] + 1; int ans; if (t1 != 0) { ans = t1; } else { ans = t2; } printf ("%d %d\n",pos[pos.size() - 1],ans); } else { for (int i = 0; i < pos.size(); i += 2) { printf ("%d %d\n",pos[i],pos[i + 1]); } } return ; } int main() { #ifdef local freopen("data.txt","r",stdin); #endif work (); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2016-08-28 19:42 stupid_one 阅读(192) 评论(0) 编辑 收藏 举报