小明开了一家糖果店。他别出心裁:
小朋友来买糖的时候,他就用这两种包装来组合。
你可以用计算机测试一下,在这种包装情况下,
本题的要求就是在已知两个包装的数量时,
输入:
两个正整数,表示每种包装中糖的颗数(都不多于1000)
要求输出:
一个正整数,表示最大不能买到的糖数
例如:
用户输入:
4 7
程序应该输出:
17
再例如:
用户输入:
3 5
程序应该输出:
7
资源约定:
峰值内存消耗 <64M
思路:比如 4 和 7 时,4 和 7 是必胜态, 1, 2, 3, 5, 6 是必败态,当糖果数大于7时, 每次只需判断两种情况即可判断出它是必胜态还是必败态:-4 和 -7之后是必胜还是必败态,当走到后面的时候,前面这两种情况一定是已经算好的。注意:若输入4 和16, 4 和16之间的数字也有可能能够组合出来,所以要从输入的两个数中最小的开始算。并且每次算之前确保它比要减去的数字大。
开一个足够大的数组,来标记能不能买到的情况,有两种办法得出最大不能买到的数目,第一种是从数组最后一个元素开始找,找到的第一个标记为0的点就是最大不能买到的数目。第二种是,在中间做一下标记,若是连续n(假设n是m, n里较小的那一个)个都能买到,那以后的就是加上n的整数倍,也就都能买到。这里把n换成m个也是一样的。
方法二:
#include<stdio.h>
#include<string.h>
int record[10000005];
int main(){
int n, m;
int i, min, max;
int count;
scanf("%d %d", &m, &n);
memset(record, 0, sizeof(record));
record[m] = record[n] = 1;
min = m < n ? m : n;
count = 0;
for(i = min + 1; i < 10000000; i++){
if(i - n > 0 && record[i - n] || i - m > 0 && record[i - m]){
record[i] = 1;
}
if(record[i] == 1){
count++;
if(count == min){
printf("%d\n", i - min);
break;
}
}
else
count = 0;
}
return 0;
}
方法一:
#include<stdio.h>
#include<string.h>
int record[10000005];
int main(){
int n, m;
int i, min, max;
int count;
scanf("%d %d", &m, &n);
memset(record, 0, sizeof(record));
record[m] = record[n] = 1;
min = m < n ? m : n;
max = m > n ? m : n;
for(i = min + 1; i < 10000000; i++){
if(i - n > 0 && record[i - n] || i - m > 0 && record[i - m]){
record[i] = 1;
}
}
for(i = 10000000 - 1; i > max; i--){
if(!record[i])
break;
}
printf("%d\n", i);
return 0;
}