题目不要求k最小,所以定住一个lucky number,反复用它进行交换。最后的结果必须是不降序,所以先确定每个位置上最终的数,若当前此位不是最终结果,就进行交换。例如第i位,若第i位上的数不满足最终结果,就用它与lucky number交换,再用lucky number和最终应该在第i位上的数交换,一共两次。这样最多交换(n-1)回合,正好满足题意交换次数<=2n。。。看似很简单,写起来很费劲,错误满篇,不得不说自己too young too simple~~~~~
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#define N 100004
#define cl(a) memset(a,0,sizeof(a))
#define pb push_back
using namespace std;
int a[N],r[N],b[N];
vector<int>c1,c2;
int check(int x)
{
while (x>0)
{
if (x%10!=4&&x%10!=7) return 0;
x/=10;
}
return 1;
}
int bin(int key,int l,int r)
{
if (r-l<=1)
{
if (b[l]==key) return l;
else return r;
}
int m=(l+r)/2;
if (key>b[m]) return bin(key,m+1,r);
else return bin(key,l,m);
}
void swaping(int p,int q)
{
int sw=a[q];
a[q]=a[p];
a[p]=sw;
c1.pb(p);
c2.pb(q);
}
int main()
{
int i,n,l=-1,k,f;
while (cin>>n)
{
for (i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
if (l<0)
{
if (check(a[i])) l=i;
}
}
sort(b+1,b+n+1);
if (l<0)
{
for (i=1;i<=n;i++) if (a[i]!=b[i]) break;
if (i>n) cout<<0<<endl;
else cout<<-1<<endl;
continue;
}
for (i=1;i<=n;i++)
{
k=bin(a[i],1,n);
while (r[k]) k++;
r[k]=i;
if (i==l) f=k;
}
for (i=1;i<=n;i++) a[r[i]]=i;
for (i=1;i<=n;i++)
{
if (a[i]!=i&&i!=f)
{
int t=a[i],l0=l;
if (i!=l)
{
swaping(i,l);
r[t]=l;l0=i;
}
if (r[i]!=l0)
{
swaping(i,r[i]);
l0=r[i];
}
l=l0;
}
}
cout<<c1.size()<<endl;
for (i=0;i<c1.size();i++)
cout<<c1[i]<<" "<<c2[i]<<endl;
}
return 0;
}