noip第15课作业

1. 累加求和

给定n(1<=n<=100),用递归的方法计算1+2+3+4+5+......+(n-1)+n.

输入:一个大于等于1的整数。

输出:输出一个整数。

【样例输入】

5

【样例输出】

15

#include <iostream>

using namespace std;
int fac(int n){
    if(n == 1)
        return 1;
    return (fac(n-1) + n);    
}
int main(){
    int n;
    cin >> n;
    cout << fac(n) << endl;
    return 0;
}

2. 苹果划分问题

给定带有编号的n个苹果(a1,a2,...,an)放入k个(0<k<=n<30)无标号的盒子中,使得没有一个盒子为空,请问一共有多少中划分的方法。

输入:一行,两个数空格隔开,第一个是苹果数量,第二个事盒子数量。

输出:一行包含一个数,表示一共有的划分数量。

【输入样例】

10 6

【输出样例】

22827

#include <iostream>

using namespace std;
int s(int n,int k){     //配合大数使用。防止数据爆掉 
    if(n < k || k == 0)
        return 0;
    if(k == 1 || k == n)
        return 1;
        //n = 3  k = 2 
        //n = 2  k  =1    方法只有1种 
        //  2  2     方法是1 *2  2   1 + 2  = 3 
    return s(n-1,k-1)+k*s(n-1,k);
    
}
int main(){
    //n是苹果数量  k是盒子数量   n=3  k=2 
    int n,k;
    cin >> n >> k;
    cout << s(n,k);
    return 0;
}

1. Pell数列

Pell数列A1,A2,A3,...的定义是这样的,A1=1,A2=2, ... ,An=2*An-1+An-2(n>2)

给出一个正整数k,要求Pell数列的第k项模上32767是多少。

输入:第一行时测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数k(1<=k<=1000000).

输出:n行,每行输出对应一个输入。输出应是一个非负整数。

【样例输入】

2

1

8

【样例输出】

1

408

#include<cstdio>  
#include<cmath>  
#include<cstring>  
#include<algorithm>  
#include<iostream>  
using namespace std;  
long long b[1000010];  
long long r[1000010]; 
long long zjf(int n){  
    if(n<3)               //设置边界  
        return n;  
    if(b[n]==0)                 //记忆化递归调用  
        b[n]=(2*zjf(n-1)+zjf(n-2))%100000;  //取mod,不让long long数组爆掉,但是为了避免统计错误,就取100000的mod  
    return (b[n]%32767);  
}  
int main()  
{  
    int n,x;  
    cin>>n;  
    for(int i=1;i<=n;i++){  
        cin>>x;  
        //cout<<zjf(x)<<endl;
        r[i] = zjf(x);  
    }  
    for(int j=1;j<=n;j++){
        cout << r[j] << endl;
    }
} 

2.  拆分自然数

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。拆分成的数字相同但顺序不同被看做是相同的方案,如3+1和1+3被看做是同一种方案。

输入:输入待拆分的自然数n。

输出:如样例输出若干个拆分方案(具体见样例)。

【样例输入】

7

【样例输出】

1+1+1+1+1+1+1

1+1+1+1+1+2

1+1+1+1+3

1+1+1+2+2

1+1+1+4

1+1+2+3

1+1+5

1+2+2+2

1+2+4

1+3+3

1+6

2+2+3

2+5

3+4

#include<bits/stdc++.h>  
using namespace std;  
int a[10000];  
int print(int n)  
{  
    for(int i=1; i<=n; i++)  
    {  
        if(i!=1)  
            printf("+");  
        printf("%d",a[i]);  
    }  
    printf("\n");  
}  
int DFS(int n,int ans)  //ans表示递归的深度,每一个深度对应 多个表达式,  
{  
    for(int i=1; i<=n/2; i++)   //后者大于等于前者  
    {  
        if(i>=a[ans-1])        //保证后一个值一定大于等于前一个值  
        {  
            a[ans]=i;  
            a[ans+1]=n-i;  
            print(ans+1);  
            DFS(n-i,ans+1);   
        }  
    }  
} 
int main()  
{  
    int n;  
    while(~scanf("%d",&n))  
    {  
        a[0]=0;  
        DFS(n,1);  
    }  
}  

3. 分数求和

输入n个分数并对他们求和,并用最简单形式表示。所谓的最简单形式是指:分母分子的最大公约数是1;若最终结果的分母为1,则直接用整数表示。

如:5/6, 10/3均是最简形式,而3/6需要化简为1/2, 3/1需要化简为3。

分子分母均不为0,也不为负数。

输入:第一行是一个整数n,表示分数个数,1<=n<=10;接下来的n行,每行一个分数,用”p/q”的形式表示,不含空格,p,q均不超过10。

输出:只有一行,即最终结果的最简形式。若为分数,用”p/q”表示。

【样例输入】

2

1/2

1/3

【样例输出】

5/6

#include<iostream>  
#include<cstdlib>  
#include<algorithm>  
#include<iomanip>  
#include<math.h>  
#include<cstdio>  
using namespace std;  
int gcd(int a,int b)//最大公约数   
{  
    if(b==0) return a;  
    return gcd(b,a%b);  
}  
int lcd(int a,int b)//最小公倍数   
{  
    int c;  
    if(a<=0||b<=0) return -1;  
    c=gcd(a,b);   
    return a*b/c;  
}  
int main()  
{     
    int n,d,num1=0,num2=1,num3=0,num4=1;  
    cin>>n;  
    char c;  
    while(n--)  
    {  
        scanf("%d%c%d",&num1,&c,&num2);  
        d=lcd(num2,num4);  
        num3=num3*d/num4+num1*d/num2;  
        num4 =d;  
        d=gcd(num3,num4);  
        if(d>1)  
        {  
            num3/=d;  
            num4/=d;  
        }  
    }  
    num4>1?printf("%d/%d",num3,num4):printf("%d",num3);  
}

猜你喜欢

转载自www.cnblogs.com/zhplovelnn/p/10383148.html