1.假如a是幸运数,b是幸运数,那么a+b+2也是幸运数。现在给你a,b,c,已知a,b是幸运数了,让你判断c是不是幸运数。
if(x <= 0 || flag)
return;
if(x == a || x == b)
{
flag = 1;
return;
}
dfs(x-a-2);
dfs(x-b-2);
while(scanf("%d %d %d", &a, &b, &c) != EOF)
{
flag = 0;
dfs(c);
if(flag)
printf("Yes\n");
else
printf("No\n");
}
int k, m, a, b, c, flag;
while(scanf("%d %d %d", &a, &b, &c) != EOF)
{
flag = 0;
for(k = 0 ; k <= (c+2)/(a+2) && !flag; k++)
for(m = 0 ; m <= (c+2)/(b+2) ; m++)
if(c == k*a+m*b+2*(k+m-1))
{
printf("Yes\n");
flag = 1;
break;
}
if(flag == 0)
printf("No\n");
}
分析:乍眼一看,觉得:卧槽,这么简单? 直接判断a+b+2是不是c不就行了。后来反映了0.01秒,发现,不对,c不一定是a,b进行一次相加得来的,可能是a+b+2+a+2,也可能是a+b+2+a+b+2+2……有好多种可能。后来通过举例2和3发现可以将c先-2,再-a,判断是不是b,如果不是,继续减,如果是,输出。然后再从头判断-b的。可是这又是个问题,这种算法只能解决a+b+2+a+2,a+b+2+a+2+a+2,a+b+2+b+2……这种从第一次二者相加之后只能一个劲儿的加其中一个的这种,如果一会加a一会加b就没法算了。灭掉了。
后来考虑的就是深搜。但是深搜不熟练。。。思路有,但不会施行,想了半天,好不容易改出来一种写法:从头开始一个劲儿地-a(其中先-2这一步我就省略不说了,但是代码还是有的),如果等于a或者b了,跳出,输出是。如果减到小于等于0了,那么回溯到上一层,开始-b,不等于a或b,就继续回溯到上一层,继续-b……
这个代码应该是可行的(没提交过,但测试数据对):
#include
int a, b, c, flag;
void dfs(int x)
{
}
int main()
{
}
但是!还有一种更好的算法,就是观察规律!因为a+b+2, a+a+2,a+b+2+a+2,a+b+2+b+2+a+b+2+2……这些都是幸运数,归纳发现,c=ka+mb+2*(k+m-1),也就是每加上一个字母,就会带来一个2,但最开头那个数不用+2,因此就是2的个数就是系数个-1。所以,直接遍历就可以了,k从0——(c+2)/(a+2), m从0——(c+2)/(b+2).
代码如下:
#include
int main()
{
}
其实,如果当时冷静想想,就会发现,这道题和百钱买百鸡差不多的(前几天刚刚看过的蓝桥题!)。回到找规律那里,假如这道题换成:a+b也是幸运数的话,很容易就想到枚举每一项系数,判断所有的系数组合。现在学了很多相对高深的东西,最基础的东西却给忘了。