全国新生赛——————————1001————————————————
Problem Description 小明现在是人见人爱,花见花开的高富帅,整天沉浸在美女环绕的笙歌妙舞当中。但是人们有所不知,春风得意的小明也曾有着一段艰苦的奋斗史。 那时的小明还没剪去长发,没有信用卡没有她,没有24小时热水的家,可当初的小明是那么快乐,尽管甚至没有一把破木吉他… 之所以快乐,是因为那时的小明心怀逆袭梦想。有一天,小明为了给他心目中的女神买生日礼物,来到了某建筑工地搬砖挣钱。就在这个时候,工地上又运来了一卡车的砖,包工头让小明把卡车卸下来的那堆砖分成一块一块的(要求任何2块转都要分开)。作为资深搬运工,小明总是每次将一堆砖分为两堆,这时候,所消耗的体力是分完之后两堆砖数目的差值。 现在,已知卡车运来的砖的数目,请告诉小明最少要花费多少体力才能完成包工头所要求的任务呢? Input 输入数据第一行是一个正整数T(T<=100),表示有T组测试数据。 接下来T行每行一个正整数N(N<=10000000),表示卡车运来的砖块的数目。 Output 对于每组数据,请输出小明完成任务所需的最少体力数。 Sample Input 2 4 5 Sample Output 0 2 S
审题之后就认为这是一道给数字出结果的题。根据根有据几块砖,去慢慢的除以而去算,结果发现越算越麻烦。
#include<stdio.h> int main() { __int64 a,i,n,s; scanf("%I64d",&n); for(i=0;i<n;i++) { int q=1; scanf("%I64d",&a); if(a==1) { printf("1\n"); continue; } if(a==0) { printf("0\n"); continue; } else if(a%2==0) { while(a%2==0) { a=a/2; q=2; if(a==1) { printf("0\n"); break; } } if(a==1) continue; s=0; while(a>0) { a=a/2; if(a%2!=0) ; else a=a+1; s=s+1; if(a==1) break; } printf("%I64d\n",s*q); } else { s=0; while(a>0) { a=a/2; if(a%2!=0) ; else a=a+1; s=s+1; if(a==1) break; } printf("%I64d\n",s); } } }
最后麻烦到你没法做,这个时候你就应该想到这是一道递推的题。下面附上正确代码。
#include<stdio.h> int main() { __int64 a,i,n,s; scanf("%I64d",&n); for(i=0;i<n;i++) { int q=1; scanf("%I64d",&a); if(a==1) { printf("1\n"); continue; } if(a==0) { printf("0\n"); continue; } else if(a%2==0) { while(a%2==0) { a=a/2; q=2; if(a==1) { printf("0\n"); break; } } if(a==1) continue; s=0; while(a>0) { a=a/2; if(a%2!=0) ; else a=a+1; s=s+1; if(a==1) break; } printf("%I64d\n",s*q); } else { s=0; while(a>0) { a=a/2; if(a%2!=0) ; else a=a+1; s=s+1; if(a==1) break; } printf("%I64d\n",s); } } }
在写出正确的代码的途中仍然遇到了很多困难比如,直接将数组开到10000009这么大,很明显int开出来的数组最大只能盛放下。‘汗’,不知道查不到,但是以后像这样中八位数的话就应该考虑一下了。还是去测试一下吧。。。测试完毕附上图
#include<stdio.h> int a[111111111]; int main() { a[111111110]=1; printf("%d",a[111111110]); return 0; }
所占用的内存约为265m 很操蛋的一个数字,所以数组不能开得太大。要多学习算法知识。