URAL 1252 ——Sorting the Tombstones——————【gcd的应用】
题目大意:给你n个数,让你求中间隔K个数可以交换两边的数时,让这n个数有序,问这个K最大是多少。 如样例:K = 1,即 56 和 17可以交换位置,21 和 40可以交换位置。
解题思路:我们可以设每个数的起始位置是idx,有序时应在的位置是dst。那么 dst = idx + K*x。 K是要求的值,x表示某个整数。那么要让所有的数都能交换到达有序的位置,那么,dst[i] = idx[i] + K[i] * x[i]。那么我们要求的K,就是所有的GCD(K[i]*x[i] , ans)。 还要注意的是,顺序包括两种,递增和递减,结果取两种的最大值。
#include<stdio.h> #include<algorithm> #include<bits/stdc++.h> #include<string.h> #include<bitset> #include<math.h> #include<iostream> using namespace std; const int maxn = 1e6; struct Stone{ int wei,idx; }stones[maxn]; int GCD(int a,int b){ return b == 0? a : GCD(b,a%b); } bool cmp1(Stone a,Stone b){ return a.wei < b.wei; } bool cmp2(Stone a,Stone b){ return a.wei > b.wei; } int main(){ int n; while(scanf("%d",&n)!=EOF){ for(int i = 1; i <= n; i++){ scanf("%d",&stones[i].wei); stones[i].idx = i; } sort(stones+1,stones+1+n,cmp1); int nn = 0, ans = 0, gcd = 0; for(int i = 1; i <= n; i++){ int tmp = abs(i - stones[i].idx); if(tmp){ nn++; gcd = GCD(gcd,tmp); } } if(nn == 0){ ans = n -1; } ans = max(ans,gcd-1); sort(stones+1,stones+1+n,cmp2); nn = 0, gcd = 0; for(int i = 1; i <= n; i++){ int tmp = abs(i-stones[i].idx); if(tmp){ nn++; gcd = GCD(gcd,tmp); } } if(nn == 0){ ans = n-1; } ans = max(ans,gcd-1); printf("%d\n",ans); } return 0; } /* 5 30 21 56 40 17 */
学学学 练练练 刷刷刷