大一上学期第一次班级对抗赛补题

题1

7-10 特殊约瑟夫问题 (10 分)
编号为1…N的N个小朋友玩游戏,他们按编号顺时针围成一圈,从第一个人开始按逆时针次序报数,报到第M个人出列;然后再从下个人开始按顺时针次序报数,报到第K个人出列;再从下一个人开始按逆时针次序报数,报到第M个人出列;再从下个人开始按顺时针次序报数,报到第K个人出列……以此类推不断循环,直至最后一人出列。请编写程序按顺序输出出列人的编号。


输入格式:
输入为3个正整数,分别表示N、M、K,均不超过1000。

输出格式:
输出为一行整数,为出列人的编号。每个整数后一个空格。

输入样例:
6 3 5
输出样例:
5 3 1 2 4 6 

一开始写的时候只是把出列的人标记,但是没有意识到当有人出列时要转向的下一个人应该是队列中没有被标记的下一个人,而不是直接队列中的下一个人。

#include<stdio.h>
int count=0,a[1005],n,m,k,flag=-1,cur=1,top=0,b[1005];
int main(){
    scanf("%d%d%d",&n,&m,&k);
    while(1){
        if(flag==1){
            while(count!=k){
                if(a[cur]==0) count++;
                if(count==k) break;
                cur++;
                if(cur>=n+1) cur=1;
            }
            a[cur]=1;
            count=0;
            b[top++]=cur;
            if(top==n) break;
            while(a[cur]==1){
                cur++;
                if(cur>=n+1) cur=1;
            }
            if(cur>=n+1) cur=1;
            flag*=-1;
        }
        else{
            while(count!=m){
                if(a[cur]==0) count++;
                if(count==m) break;
                cur--;
                if(cur<=0) cur=n;
            }
            a[cur]=1;
            count=0;
            b[top++]=cur;
            if(top==n) break;
            while(a[cur]==1){
                cur--;
                if(cur<=0) cur=n;
            }
            if(cur<=0) cur=n;
            flag*=-1;
        }
        
    }
    for(int i=0;i<n;i++){
        printf("%d ",b[i]);
    }
    return 0;
}

题2

7-9 N个数求和 (20 分)
本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

输入格式:
输入第一行给出一个正整数N(≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

输出格式:
输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

输入样例1:
5
2/5 4/15 1/30 -2/60 8/3
结尾无空行
输出样例1:
3 1/3
结尾无空行
输入样例2:
2
4/3 2/3
输出样例2:
2
输入样例3:
3
1/3 -1/6 1/8
输出样例3:
7/24

这题写辗转相除法写wa了(?)应该是求余==0时结束,写成了1...

还要做0的特判 用至少long int

#include<stdio.h>
long long a[105],b[105],max=1,n,num1=0,num2=0;
long long xxx(long long a,long long b);
int main(){
    scanf("%lld",&n);
    if(n==0) return 0;
    else{
        for(long long i=0;i<n;i++){
            scanf("%lld/%lld",&a[i],&b[i]);
        }
        for(long long i=0;i<n;i++){
            long long tem;
            tem=xxx(max,b[i]);
            if(b[i]*max/tem>max) max=b[i]*max/tem;
        }
        for(long long i=0;i<n;i++){
            if(a[i]!=0){
                long long tem_num1=max/b[i];
                num2+=tem_num1*a[i];
            }
        }
        num1+=num2/max;
        num2=num2%max;
        if(num2!=0){
            m=xxx(num2,max);num2/=m;max/=m;
        }
        if(num2==0) printf("%lld",num1);
        else if(num1==0) printf("%lld/%lld",num2,max);
        else printf("%lld %lld/%lld",num1,num2,max);
    }
    return 0; 
}
long long xxx(long long a,long long b){
    long long tem1=b%a,tem2=a;
    while(tem1!=0){
        long long tem3=tem2%tem1;
        tem2=tem1;tem1=tem3;
    }
    return tem2;

}

 

posted @ 2021-12-19 22:34  m2on  阅读(188)  评论(0编辑  收藏  举报