5 5
6 1
样例输出
7
1
说明:
对于输入5 5,有7种放法,分别是
(1) 5个小球都放在一个盒子里,剩下4个盒子都是空的;
(2) 4个小球放在一个盒子里,1个小球放在一个盒子里,剩下3个盒子是空的;
(3) 3个小球放在一个盒子里,2个小球放在一个盒子里,剩下3个盒子是空的;
(4) 3个小球放在一个盒子里,1个小球放在一个盒子里,1个小球放在一个盒子里,剩下2个盒子是空的;
(5) 2个小球放在一个盒子里,2个小球放在一个盒子里,1个小球放在一个盒子里,剩下2个盒子是空的;
(6) 2个小球放在一个盒子里,1个小球放在一个盒子里,1个小球放在一个盒子里,1个小球放在一个盒子里,剩下1个盒子是空的;
(7) 5个盒子每个盒子里放一个小球。
对于输入6 1,有1种方法。
小球和盒子问题的思路网上有很详细的讲解,下边推荐两个链接
https://www.zhihu.com/question/21731092
https://blog.csdn.net/zwz_511/article/details/46240927
这两个链接里就有正确的答案,只修要稍微修改一下,将只能接收一组数据改为接收多组数据就好了,这个部分是这个题的难点
注意:题目中只是说允许多行输入但是并没有给出输入的结束条件,所以我的第一反应是当下一次输入为空也就是只有一个回车换行而没有数据时,输入结束,但写完提交全错以后打开反馈的测试数据发现每一组数据最后的两组数是完全一致的,所以,只能重新修改逻辑去匹配它的结束条件。
满分通过的代码
#include
#include
int f(int n, int m)
{
if(m == 1 || n == 0) return 1;
if(m > n) return f(n, n);
return f(n, m-1) + f(n-m, m);
}
int main() {
int a,b,j,result;//a,b分别是题目中的n,m;j是下边for循环的循环标志,result是最后的结果
int a1 = 0;
int b1 = 0;//通过a1,b1是否与上一组a,b值相等来控制输入的结束(这个只能通过测试用例分析出来,差点坑死)
int* store;//用来暂存所有的输入
int i = 0;//标记总共有多少个数据,2个一组
store = (int*)malloc(sizeof(int));
scanf("%d %d",&a,&b);
*(store+i) = a;
i++;
*(store+i) = b;
i++;
while((a==a1)?((b==b1)?0:1):1){//a!=a1 && b!=b1判断是错的
a1 = a;
b1 = b;
scanf("%d %d",&a,&b);
*(store+i) = a;
i++;
*(store+i) = b;
i++;
}
for(j=0;j2;){
a = *(store+j);
j++;
b = *(store+j);
j++;
result = f(a,b);
printf("%d\n",result);
}
return 0;
}
下边java和C的代码是,当最初按自己的想法写的控制多行输入的代码,一起粘一下,测试的输出语句都没删,C写的有点复杂
C:
#include
#include
#include
//自己电脑环境里能够正常运行,提交报错,唯一区别是傻的在输入结束条件上下了很大功夫关键还是错的
int f(int n, int m)
{
if(m == 1 || n == 0) return 1;
if(m > n) return f(n, n);
return f(n, m-1) + f(n-m, m);
}
int main(){
int i = 0;
int j,n,m,result;
char cn,cm;
char** p;
char* p1;
char* p2;
p = (char**) malloc(sizeof(char*));
p1 = (char*) malloc(sizeof(char));
p2 = (char*) malloc(sizeof(char));
gets(p1);//gets能够获取的空格,scanf的话碰到空格就是分割符
*(p+i) = p1;
//printf("*(p+%d)%s\n",i,*(p+i));
//printf("%s\n",p1);
while(strlen(p1)){
i++;
p1 = (char*) malloc(sizeof(char));
gets(p1);//gets能够获取的空格,scanf的话碰到空格就是分割符
*(p+i)= p1;
//printf("*(p+%d)%s\n",i,*(p+i));
//printf("%s\n",p1);
}
//printf("i=%d\n",i);
//printf("*(p+0)%s\n",*(p+0));
for(j=0;j//printf("p2=%s\n",p2);
//printf("strlen(p2)=%d\n",strlen(p2));
//printf("*(p2+0)=%c\n",*(p2+0));
//printf("*(p2+1)=%c\n",*(p2+1));
//printf("*(p2+2)=%c\n",*(p2+2));
n = (int)*(p2+0) - 48; //转换成对应的整形数字
//printf("n=%d\n",n);
m = (int)*(p2+2) - 48;//转换成对应的整形数字
//printf("m=%d\n",m);
result = f(n,m);
printf("%d\n",result);
}
return 0;
}
java:
import java.util.Scanner;
public class Boxs {
public static void main(String[] args) {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
Scanner in = new Scanner(System.in);
String s = in.nextLine();
sb.append(s);
while (s.length() != 0) {
s = in.nextLine();// 只有回车换行也算是有字符,能够获取到
sb.append(" " + s);
}
String input = sb.toString();
String[] divide = input.split(" ");
int len = divide.length;
for (int i = 0; i < len;) {
int n, m;
n = Integer.parseInt(divide[i]);
i++;
m = Integer.parseInt(divide[i]);
i++;
System.out.println(f(n, m));
}
}
static int f(int n, int m) {
if (m == 1 || n == 0)
return 1;
if (m > n)
return f(n, n);
return f(n, m - 1) + f(n - m, m);
}
}