Codeforces Testing Round #3 B

 

  前几天做的一场cf,虽然是no rated。题目也不简单,做了俩,B一交上就被hack掉了。其实也是不会,乱写的,把样例过了就交了。

  看了别人的代码看了好久也没明白。cf没有题解也是很纠结。我以前尝试过写div2的题解,要么是太晚了,要么是就会最水的水题。cf不如tc那么有影响,做的人自然也就少了。

 

  题目是这样,一个数对(a,b)可以变换为(a+b,b)和(a,a+b)。给出(1,1),要求变换成(n,x)或者(x,n)最小的步数。x是随意的。

  首先要考虑一点就是n>x。因为n=n‘ + x或者x=n+x'。如果上一步已经得到n那何必还算这一步呢?所以后一种情况是可以排除的。

  其次,GCD(n,x) 等于 1。如果>1说明x是n的一个因子,假设n=kx。那么最后的结果就是(kx,x)(或者(x,kx),不再赘述),那样的话当k>1的时候kx始终>x,

所以kx是由((k-1)x,x)得到的。依次类推,当k=1的时候状态为(x,x)。这种情况不可能存在。因为x=x+0。

  

  所以:可以直接从1到n枚举x。如果GCD(n,x)==1。则计算到达(n,x)需要的步数,然后取最小的步数即可。

   

template<class T> inline T GCD(T a, T b)
{if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}

int cal(int n, int i){
if (i == 1)
return n - 1;
return n / i + cal(i, n % i);
}


int main(){

int n;
cin >> n;
int ans = 1 << 29;

for (int i = 1; i <= n; i++)
if (GCD(i, n) == 1){
ans = min(ans, cal(n, i));
}

cout << ans << endl;

return 0;
}


 


 

posted @ 2011-12-04 21:53  like@neu  阅读(210)  评论(0编辑  收藏  举报