NEFU要崛起——第4场

比赛地址:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=17831#overview

第1题:一个类似论坛的模拟,要你给出服务器发出的字符长度,可能加用户,减用户,每次都是群发

分析:一开始还想模拟用户增减,后来发现根本不用,因为操作都是合法的,所以只要开一个变量统计总人数,每次发出长度就能计算了

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char s[111];
int i,ans,num;
int main()
{
    num=ans=0;
    while(gets(s))
    {
        if(s[0]=='+')++num;
        else if(s[0]=='-')--num;
        else
        {
            for(i=0;i<strlen(s);++i)
                if(s[i]==':')break;
            ans+=(strlen(s)-i-1)*num;
        }
    }
    printf("%d\n",ans);
    return 0;
}


第2题:给你一段文章,要你对它做居中排序。。。

分析:当一个字符串无法居中,也就是左右长度不一,交替靠左靠右排。。。纯粹靠眼力啊,我这样老眼昏花的,注定悲剧。。。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mm=1111;
char s[mm][mm];
int i,n,m,ml,w,a,b;
void outc(int m,char c)
{
     while(m--)printf("%c",c);
}
int main()
{
    n=0;
    while(gets(s[n]))++n;
    for(ml=i=0;i<n;++i)
        ml=max(ml,(int)strlen(s[i]));
    outc(ml+2,'*');
    puts("");
    for(w=i=0;i<n;++i)
    {
        printf("*");
        m=ml-strlen(s[i]);
        a=m/2;
        if(m&1)a+=w,w=w^1;
        b=m-a;
        outc(a,' ');
        printf("%s",s[i]);
        outc(b,' ');
        printf("*\n");
    }
    outc(ml+2,'*');
    puts("");
    return 0;
}


第3题:要求最长的合法括号对的长度,还有他的个数

分析:由于这个最长的肯定在某段区间里,那么我们把能匹配的括号都删掉,剩下那些没匹配的括号的下标,正好可以用来计算匹配掉的长度,直接统计就行了,具体用一个栈结构来搞

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mm=2222222;
int p[mm];
char s[mm],q[mm];
int i,j,m,n,ans,sum;
int main()
{
    while(~scanf("%s",s))
    {
        n=strlen(s);
        p[m=0]=-1;
        for(i=0;i<n;++i)
            if(!m||q[m]==')'||s[i]==q[m])q[++m]=s[i],p[m]=i;
            else --m;
        p[++m]=n;
        ans=-n;
        for(i=0;i<m;++i)
            if(p[i+1]-p[i]-1>ans)ans=p[i+1]-p[i]-1,sum=1;
            else if(p[i+1]-p[i]-1==ans)++sum;
        if(ans>0)printf("%d %d\n",ans,sum);
        else puts("0 1");
    }
    return 0;
}



第4题:给你一条公路,在路上的一点限制速度,要求到那点的速度小于w,给出所有信息,求最快多久通过整条公路

分析:物理题一个,比赛时忘记写一个情况挂了(明明当时考虑了,就是忘写上去),首先分两种情况,一种是车怎么加速,到限速点的速度都不会超速,那么直接加速开就行,别忘记速度上限,第二种情况比较麻烦,以为一直加速会导致超速,那么在减速点之前,我们先加速到w,然后剩下的那段路程,先加速,再减速到w即可(别忘记超过上限v就不能加速了,我因此wa了),这个加速和减速的距离是一样的,所以可以把路程除二方便计算,当然,如果会超过v,那就更好计算了,这些都得考虑,最后剩下l-d的距离,直接加速到底,同样考虑上限v后匀速。。。。总之烦人的题,这次考虑的还算清晰,就是写代码时忘记了,哎= =

代码:

#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
double a,v,w,l,d,t,t1;
double fun(double a,double b,double c)
{
    double del=b*b-4*a*c;
    if(del<0)return 0;
    return (-b+sqrt(del))/(2*a);
}
int main()
{
    while(~scanf("%lf%lf%lf%lf%lf",&a,&v,&l,&d,&w))
    {
        if(v<=w||(0.5*w*w>=a*d))
        {
            t=v/a;
            if(0.5*v*t>=l)printf("%.12lf\n",sqrt(2*l/a));
            else
            {
                t=t+(l-0.5*v*t)/v;
                printf("%.12lf\n",t);
            }
        }
        else
        {
            t=(v-w)/a;
            if(0.5*v*v/a+v*t-0.5*a*t*t>=d)
            {
                t=w/a;
                t=t+fun(a,2*w,0.5*a*t*t-d)*2;
            }
            else t=v/a+(v-w)/a+(d-(0.5*v*v/a+v*t-0.5*a*t*t))/v;
            t1=(v-w)/a;
            if(w*t1+0.5*a*t1*t1+d>=l)t=t+fun(0.5*a,w,d-l);
            else
            {
                l=l-(w*t1+0.5*a*t1*t1+d);
                t=t+t1+l/v;
            }
            printf("%.12lf\n",t);
        }
    }
    return 0;
}


第5题:给出一个环状的n座山,问有多少对山相互可见,要求在他们之间的山都不高于他们

分析:我们从左向右扫描,当前一座山比当前的山低时,他一定不能被后面的山看到,所与把他从队列中删除是正确的,删除的时候同时答案加1,直到前面没有山比当前山低,然后继续增加山,那么边界的情况怎么处理,而且它不是能向两边观望吗?直接选取最高的山当作第一座山和最后一座山即可,最后一座山删除时得留下一座,以免重复计算,这样就行了吗?我就这样wa了一次,其实还有一样高的山,这些得特殊计算。。。具体就是利用n*(n-1)/2这个公式来算,还有答案会超int得注意下

代码:

#include<cstdio>
#include<iostream>
using namespace std;
const int mm=1111111;
int a[mm],q[mm];
int i,j,l,n;
long long r,ans;
int main()
{
    while(~scanf("%d",&n))
    {
        for(l=i=0;i<n;++i)
        {
            scanf("%d",&a[i]);
            if(a[i]>a[l])l=i;
        }
        q[ans=r=0]=a[l];
        for(i=l+1;(i%n)!=l;++i)
        {
            j=1;
            while(r&&a[i%n]>q[r])
            {
                ans+=j;
                if(q[r-1]==q[r])++j;
                else j=1;
                --r;
            }
            q[++r]=a[i%n];
            ++ans;
        }
        j=1;
        while(r>1&&a[l]>q[r])
        {
            ans+=j;
            if(q[r-1]==q[r])++j;
            else j=1;
            --r;
        }
        if(r>1)
        {
            ++ans;
            ans=ans+r*(r+1)/2-r-1;
        }
        cout<<ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(NEFU要崛起——第4场)