北京信息科技大学校赛(全部题解)

A. paulzhou的完美算术教室

【思路分析】直接预处理出每个点的坐标,然后直接暴力求一下距离就好了。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
char s[10003];
struct node
{
    double x,y;
} a[10033];

double distan(node x,node y)
{
    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
int main()
{
    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        gets(s);
        int l=strlen(s);
        int x=0;
        int pos=0;
        double num=0;
        int f=0;
        for(int i=0; i<l; i++)
        {

            if(s[i]==',')
            {
                a[pos].x=num;
                num=0;
            }
            else if(s[i]==')')
            {
                a[pos].y=num;
                num=0;
                pos++;
            }
            else if(s[i]=='('||s[i]==' ')
                continue;
            else
            {
                num*=10;
                num+=s[i]-'0';
            }
        }
        double minn=10000003;
        for(int i=0; i<pos; i++)
        {
            for(int j=i+1; j<pos; j++)
            {
                minn=min(distan(a[i],a[j]),minn);
            }
        }
        printf("%.4f\n",minn);
    }
    return 0;
}

B. An easy problem
【思路分析】直接暴力枚举每个子串就好了。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

struct node
{
    int x,y;
};

char str[205];

int bfs(int s,int t)
{
    int x=0,y=0;
    for(int i=s;i<=t;i++)
    {
        if(str[i]=='U')
        {
            y+=1;
        }
        if(str[i]=='D')
        {
            y-=1;
        }
        if(str[i]=='L')
        {
            x-=1;
        }
        if(str[i]=='R')
        {
            x+=1;
        }
    }
    if(x==0&&y==0)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int len;
        scanf("%d",&len);
        scanf("%s",str);
        int re=0;
        for(int i=0;i<len;i++)
        {
            for(int j=i+1;j<len;j++)
            {
                if(bfs(i,j))
                    re++;
            }
        }
        printf("%d\n",re);
    }
    return 0;
}

C. 善良的XLAOSHI
【思路分析】直接对运气和考试难度sort一下,然后从高到低判断满足的个数就好了。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int a[30005],b[30005];
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&b[j]);
        }
        sort(b+1,b+1+m);
        sort(a+1,a+1+n);
        if(n>m)
        {
            printf("Time up!\n");
        }
        else
        {
            int ans=0;
            for(int i=n,j=m;i>=1&&j>=1;i--)
            {
                if(a[i]<=b[j])
                {
                    j--;
                    ans++;
                }
            }
            if(ans==n)
            {
                printf("You are pretty lucky!\n");
            }
            else
            {
                printf("Time up!\n");
            }
        }
    }
    return 0;
}

D. 环游四边形
【思路分析】画了n久图画出来一个结论,其实就是2*对角线长度。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long int a,x,y;
        scanf("%lld %lld %lld",&a,&x,&y);
        if((x==0&&y==0)||(x==0&&y==a)||(x==a&&y==0)||(x==a&&y==a)||x==y)
        {
            printf("%.6lf\n",2*sqrt(a*a+a*a));
        }
        else
        {
            double x1=x+(a-y);
            double re=2*sqrt(2*x1*x1)+2*sqrt(2*(a-x1)*(a-x1));
            double y1=y+(a-x);
            double re2=2*sqrt(2*y1*y1)+2*sqrt(2*(a-y1)*(a-y1));
            printf("%.6lf\n",min(re,re2));
        }
    }
    return 0;
}

E. 一道很水很水很水的签到题
【思路分析】直接输出就好了。
【AC代码】

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;

int main()
{
    printf("ya mie die\n");
    return 0;
}

F. Make Anonymous be the lucky guy
【思路分析】直接枚举0到100的每个数就好了,优化就是记录一下每个数的个数。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int a[105],book[105];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int sum=0;
        memset(book,0,sizeof(book));
        for(int i=1;i<n;i++)
        {
            scanf("%d",&a[i]);
            book[a[i]]++;
            sum+=a[i];
        }
        int maxn=0;
        for(int i=0;i<=100;i++)
        {
            sum+=i;
            if(4*i*n<=3*sum)
            {
                //printf("111\n");
                if(i>maxn)
                {
                    maxn=i;
                }
            }
            sum-=i;
        }
        printf("%d %.2f\n",maxn,1.0/(double)(book[maxn]+1));
    }
    return 0;
}

G. 当然选择原谅她呀
【思路分析】直接跑一遍bfs就好了,注意标记一下,不然会TLE。
【AC代码】

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;

struct node
{
    int x,y,step;
};
int a[105][105],book[105][105];
int n,m;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int bfs(int sx,int sy)
{
    memset(book,0,sizeof(book));
    queue<node>q;
    node fr,ne;
    fr.x=sx,fr.y=sy,fr.step=0;
    book[sx][sy]==1;
    q.push(fr);
    while(!q.empty())
    {
        fr=q.front();
        q.pop();
        if(fr.x==n&&fr.y==m)
        {
            return fr.step;
        }
        for(int i=0;i<4;i++)
        {
            ne.x=fr.x+dir[i][0];
            ne.y=fr.y+dir[i][1];
            ne.step=fr.step+1;
            if(a[ne.x][ne.y]==0&&book[ne.x][ne.y]==0&&ne.x>=1&&ne.x<=n&&ne.y>=1&&ne.y<=m)
            {
                book[ne.x][ne.y]=1;
                q.push(ne);
            }
        }
    }
    return -1;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        int re=bfs(1,1);
        printf("%d\n",re);
    }
    return 0;
}

H. paulzhou和他的学弟们
【思路分析】逆向思维考虑一下,其实就是构造一棵哈夫曼树,然后用优先队列维护一下就好了。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
#define LL long long

struct node
{
    LL x;
    bool friend operator <(node a,node b)
    {
        return a.x>b.x;
    }
};

LL a[1005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        LL n,k;
        scanf("%lld%lld",&n,&k);
        priority_queue<node> pq;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            node no;
            no.x=a[i];
            pq.push(no);
        }
        LL sum=0;
        while(!pq.empty())
        {
            LL x=pq.top().x;
            pq.pop();
            if(pq.empty())break;
            else
            {
                LL y=pq.top().x;
                pq.pop();
                //printf("%lld %lld\n",x,y);
                sum+=(x+y);
                node no;
                no.x=x+y;
                pq.push(no);
            }
        }
        if(n!=1)
        printf("%lld\n",n*k+sum);
        else
        {
            printf("%lld\n",k+a[1]);
        }
    }
    return 0;
}

I. paulzhou的数学?TAT?
【思路分析】直接找出最大的是5的数,剩下的就是判断了,注意0的时候是TAT。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

char str[10005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",str);
        int len=strlen(str);
        if(len>10)
        {
            printf("TAT\n");
        }
        else if(len==10&&strcmp("4294967296",str)<=0)
        {
            printf("TAT\n");
        }
        else
        {
            long long n=0;
            for(int i=0;i<len;i++)
            {
                n=n*10+(str[i]-'0');
            }
            if(n==0)
            {
                printf("TAT\n");
                continue;
            }
            int re=0;
            for(int i=1;i<=5;i++)
            {
                if(n==1)break;
                re++;
                n=(long long)sqrt(n);
            }
            printf("%d\n",re);
        }
    }
    return 0;
}

/*
4294967296
*/

J. 小可爱
【思路分析】
其实这个题是原题,之前在hihocoder做过,直接暴力就可以了。

#include<iostream>
#include<string>
#include<cstdio>
using namespace std;

char in[3]= {'A','B','C'};
string getstring(string str)
{
    int l=str.length();
    if(l<=1) return str; //这里需要注意
    string ss="";
    for(int i=0; i<l-1; i++)
    {
        if(str[i]==str[i+1])
        {
            while(i+1<l&&str[i]==str[i+1]) i++;
        }
        else ss+=str[i];
    }
    if(str[l-1]!=str[l-2]) ss+=str[l-1];
    return ss;
}
int main()
{
    int t,max;
    string s;
    cin>>t;
    while(t--)
    {
        cin>>s;
        max=0;
        for(int i=0; i<s.length()-1; i++)
        {
            for(int j=0; j<3; j++) //两重循环枚举。
            {
                string str=s.substr(0,i+1)+in[j]+s.substr(i+1);
                int len=str.length();
                str=getstring(str);
                while(len>str.length())
                {
                    len=str.length();
                    str=getstring(str);
                }
                if(s.length()-len+1>max)  max=s.length()-len+1;
            }
        }
        cout<<max<<endl;
    }
    return 0;
}

K. paulzhou和方程
【思路分析】
这个题很迷,数据中的n超范围了,超了一个数量级,好气的,然后就是找一下循环节求一下倍数就可以了。
【AC代码】

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define LL long long
#define N 10005
#define mod 10007

LL c[N];
LL n;
LL f(LL x)
{
    LL base=1;
    LL ans=0;
    for(LL i=0; i<=n; i++)
    {
        ans+=((c[i]%mod)*(base));
        ans%=mod;
        base*=x;
        base%=mod;
    }
    return ans;
}
LL F[N],sum[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%lld",&n);
        for(LL i=0; i<=n; i++)
            scanf("%lld",&c[i]);
        LL k;
        scanf("%lld",&k);
        sum[0]=F[0]=f(0);
        if(k>10006)
        {
            for(LL i=1; i<=10006; i++)
                F[i]=f(i),sum[i]=sum[i-1]+F[i],sum[i]%=mod;
            k--;
            LL bei=k/10007;
            bei%=mod;
            k%=10007;
            LL ans=(bei*sum[10006])%mod;
            ans+=sum[k];
            ans%=mod;
            printf("%lld\n",ans);
        }
        else
        {
            for(LL i=1; i<=k; i++)
                F[i]=f(i),sum[i]=sum[i-1]+F[i],sum[i]%=mod;
            printf("%lld\n",sum[k-1]%10007);
        }
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值