天梯赛训练总结2

昨天是天梯赛训练第二天,比第一天训练有一点点好转(前期还行 后期打得就开始有点拉跨了)

7-2 N个数求和 (20 point(s))
 

本题的要求很简单,就是求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

这道题目主要是对每个数字在相加的时候每两个两个相加并且取得分母的最小公倍数
两个数字的最小公倍数则是两个数的乘积除以两个数字的最大公因数,而两个数字的最大公因数则是使用辗转相除的办法来解决
这道题目一直都是17分,然后赛后想了好几个案例都没有过,但是赛后把int 全部改成long long 竟然都奇迹般的过了

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
long long gcd(long long x,long long y)
{
    long long temp;
    while(x%y!=0)
    {
        temp=x%y;
        x=y;
        y=temp;
    }
    return y;
}
long long fz[110];
long long fm[110];
int main()
{
    int n;
    cin>>n;
    int a,b;
    int c,d;
    scanf("%lld/%lld",&fz[1],&fm[1]);
    //cout<<fz[1]<<" "<<fm[1]<<endl;
    int i;
    for(i=2;i<=n;i++)
    {
        scanf("%lld/%lld",&fz[i],&fm[i]);
    //    cout<<fz[i]<<" "<<fm[i]<<endl;
        long long gbs=fm[i]*fm[i-1]/gcd(fm[i],fm[i-1]);
    //    cout<<gbs<<endl;
    //    cout<<(gbs/fm[i-1])*fz[i-1]<<" "<<(gbs/fm[i])*fz[i]<<endl;
        long long zj=(gbs/fm[i-1])*fz[i-1]+(gbs/fm[i])*fz[i];
        fz[i]=zj;
        fm[i]=gbs;
        //cout<<fz[i]<<endl;
    //    cout<<fm[i]<<" "<<fz[i]<<endl;
        long long gys=abs(gcd(fz[i],fm[i]));
    //    cout<<gys<<endl;
        fz[i]/=gys;
        fm[i]/=gys;
        //cout<<fz[i]<<" "<<fm[i]<<endl;
    }
    long long gys=abs(gcd(fz[n],fm[n]));
    fz[n]/=gys;
    fm[n]/=gys;
//    cout<<fz[n]<<" "<<fm[n]<<endl;
    if(fz[n]==0)
    {
        cout<<"0"<<endl;
        return 0;
    }
    if(abs(fz[n])>=abs(fm[n]))
    {
        cout<<fz[n]/fm[n];
        fz[n]=fz[n]%fm[n];
        if(fz[n]!=0) cout<<" ";
    }
    if(fz[n]!=0) cout<<fz[n]<<"/"<<fm[n];
    cout<<endl;
    return 0;
}
/*2
-1/9 1/10
*/

(比赛的时候辗转相除法差点都没写出来)小声bb

 

 

L2-008 最长对称子串 (25 point(s))
 

对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。

输入格式:

输入在一行中给出长度不超过1000的非空字符串。

输出格式:

在一行中输出最长对称子串的长度。

输入样例:

Is PAT&TAP symmetric?
 

输出样例:

11

tips:注意边界处理问题,比赛的时候一直有一个点过不去,然后今天把maxlen修改一下初始就可以过了
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
char zf[1010];
int main()
{
    cin.getline(zf,1010);
//    cout<<zf<<endl;
    int len=strlen(zf);
    int maxlen=1;
    int slen=0;
    int lmark,rmark;
    int r,l;
    for(int i=1;i<=len-2;i++)
    {
        slen=1;
        if(zf[i+1]==zf[i])
        {
            lmark=i-1;
            rmark=i+1+1;
            slen++;
        }
        else
        {
            lmark=i-1;
            rmark=i+1;
        }
//        cout<<lmark<<" "<<rmark<<"??!!"<<endl;
        int maxn=min(i,len-i);
        for(int j=1;j<=maxn;j++)
        {
            if(lmark<0||rmark>=len) break;
            if(zf[lmark]==zf[rmark])
            {
                lmark--;
                rmark++;
                slen+=2;
            }
        }
    //    cout<<slen<<endl;
        if(slen>maxlen)
        {
            maxlen=slen;
            //r=rmark;
            //l=lmark;
            //cout<<l<<" "<<r<<endl;
        }
    }
//    if(maxlen==1) maxlen=0;
//    cout<<r<<" "<<l<<endl;
    cout<<maxlen<<endl;
    return 0;
}
View Code

 

posted @ 2021-03-11 19:14  Treasure-  阅读(57)  评论(0)    收藏  举报