题:给定两个整数a和b,这两个数的取值均在【-2000,2000】区间中。把对a进行一系列操作得到b的过程称为a到b的路径,可选操作包括:加12、减12、加7、减7、加5、减5。例如-5至19的的一条路径为(-5,7,19)。现要求编写程序,对任何a和b,求a至b的最短路径。
可以知道1有 5 5 5 -7 -7组成
f(1) = 5 5 5 -7 -7
求b-a的差值 c
n12 = c/12
n7 = c%12/7
n5 = c%12%7/5
最后剩下要组合的数就是1 -4之间的数了
因为我们之前都是按照先加大数的原则,所以在组合1-4之前,路径都是最短的
4*f(1)就会出现有8个-7,然后拿n12个12去抵消-7得5,这样就消去两个数,增加一个数,
上面的算法有错误:
可能出现的组合只能是
12,5(5的数量要小于12)
12,7(7的数量要小于12)
5 ,-7(-7的数量要小于5)
-5, 7(-5的数量要小于7,要么7个数小于5)
http://blog.csdn.net/gogdizzy/article/details/6563626
/**
* 用5,7,12加减运算,最少步骤到大n
* gogdizzy@gmail.com
*/
#include <stdio.h>
#define abs(x) /
( (x^(x>>31))-(x>>31) )
int min_step( int N )
{
int diff;
int n5, n7, n12;
int r5, r7, r12;
unsigned tmp, total = unsigned (-1); // assign a very big num
for( n5 = -6; n5 < 7; ++n5 )
{
diff = N - 5 * n5;
n7 = diff / 7;
n12 = diff / 12;
if( 12 * n12 + 5 * n5 == N )
{
tmp = abs( n5 ) + abs( n12 );
if( total > tmp ) r5 = n5, r7 = 0, r12 = n12, total = tmp;
}
else if( 7 * n7 + 5 * n5 == N )
{
if( n7 > -12 && n7 < 12 )
{
tmp = abs( n5 ) + abs( n7 );
if( total > tmp ) r5 = n5, r7 = n7, r12 = 0, total = tmp;
}
}
}
for( n7 = -11; n7 < 12; ++n7 )
{
n12 = ( N - 7 * n7 ) / 12;
if( 7 * n7 + 12 * n12 == N )
{
tmp = abs( n7 ) + abs( n12 );
if( total > tmp ) r5 = 0, r7 = n7, r12 = n12, total = tmp;
}
}
printf( "%d = (%d) * 5 + (%d) * 7 + (%d) * 12/ntotal:%d/n", N, r5, r7, r12, total );
return total;
}
int main()
{
int n;
scanf( "%d", &n );
min_step( n );
return 0;
}