小菜前面的博客中讲到自己不小心ac了本拉登(hdu1085),其中代码有一段
if(!jud(s,0,a+2*b))//若都可以表示
这段函数本是为了减少算法的复杂度,只要前面有没标记的说明有数字已经不可以表示,直接输出,无需在进行下一次判断。
但是这样并不对!这段代码有bug,因为我前面不能表示的数字,有了后面的硬币后说不定就可以表示了。
由于这个题目1 2 5 的局限性,我的这段代码才可以ac。消除bug的方法很简单,把这句改成
if(!jud(s,0,5-1))
就行,因为5(或者你换成其他任意的钱币m)是不能表示m-1以下数目的钱数的。
当然因为这个题目数据不好,它定为1 2 5,产生了特殊性,于是还有很多特殊解法,几行就可以ac了。
下面给出代码
方法一:
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 #define Min(a,b) (a < b ? a : b) 5 #define Max(a,b) (a > b ? a : b) 6 7 8 int main() 9 { 10 int a,b,c; 11 while(scanf("%d%d%d",&a,&b,&c)!=EOF) 12 { 13 if(a == 0 && b == 0 && c == 0) 14 { 15 break; 16 } 17 if(a == 0) 18 { 19 printf("1 "); 20 continue; 21 } 22 if(a + 2 * b < 4) 23 { 24 printf("%d ",a + 2 * b + 1); 25 continue; 26 } 27 printf("%d ",a + 2 * b + 5 * c + 1); 28 } 29 return 0; 30 }
方法二
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int a,b,c; 6 while(cin>>a>>b>>c) 7 { 8 if(a==0&&b==0&&c==0) 9 break; 10 if(a==0) 11 cout<<"1"<<endl; 12 else if(a==1&&b==1||a==3&&b==0) 13 cout<<"4"<<endl; 14 else if(a==1&&b==0 ) 15 cout<<"2"<<endl; 16 else if(a==2&&b==0) 17 cout<<"3"<<endl; 18 else 19 cout<<a+b*2+c*5+1<<endl; 20 } 21 22 return 0; 23 }
这样的解法确实简单,但是如果题目把1 2 5换成任意的a b c呢?
这时只有母函数和我打表的方法才靠得住啊!
特题特解要了解,通法通解要掌握。嗯嗯,说得好哈,忍不住要赞自己一个!