zoukankan      html  css  js  c++  java
  • 第六届山东省省赛题解

    A - Nias and Tug-of-War

    题意:

    给出n个人的身高和体重

    要求按身高排序后

    奇数序号的人一队,偶数序号的人一队

    体重大的一队获胜

    题解:

    水题,考察点是结构体的排序

    要注意的是变量的初始化以及数据类型的精度和输入

    代码:

    struct Node {
        double w, h;
    } a[110];
    
    bool cmp (Node a, Node b) {
        return a.h < b.h;
    }
    
    int main()
    {
        int t, n;
        scanf("%d", &t);
        while (t--) {
            scanf("%d", &n);
            for (int i = 0; i < n; i++) {
                scanf("%lf %lf", &a[i].h, &a[i].w);
            }
            
            sort(a, a+n, cmp);
            double s1, s2;
            s1 = s2 = 0;
            for (int i = 0; i < n; i++) {
                if (i % 2) {
                    s1 += a[i].w;
                } else {
                    s2 += a[i].w;
                }
            }
    
            if (s1 > s2) {
                printf("blue
    ");
            } else if (s1 < s2) {
                printf("red
    ");
            } else {
                printf("fair
    ");
            }
        }
        return 0;
    }

    B - Lowest Unique Price

    题意:

    给出N种操作,每种操作都由字母表示,当输入为b时,输入一个整数x,代表顾客对产品的出价,当输入为c是,输入一个整数x,代表取消之前价格为x的出价,当输入为q是,询问当前对产品的出价中只出现过一次的最小的价格,如果存在,输出该最小值,如果不存在,输出none。

    题解:

    开辟一个数组,用下标表示价格,该下标下元素的值代表该价格的出价次数,每当顾客出价时,将元素加一,并记录下当前出价的最大值max,若操作为取消之前的价格,就将数组减一即可;最后询问最小值的之后只要从一开始遍历到出价的最大值,找到第一个值为一的元素即可;

    #include<stdio.h>
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,a[200005]={0},max=0,x;
            char c;
            scanf("%d",&n);
            getchar();
            for(int i=0;i<n;i++)
            {
                c=getchar();
                if(c=='b')
                {
                    scanf("%d",&x);
                    a[x]++;
                    if(x>=max)
                        max=x;
                }
                if(c=='c')
                {
                    scanf("%d",&x);
                    a[x]--;
                }
                if(c=='q')
                {
                    int flag=0,t;
                    for(int j=1;j<=max;j++)
                        if(a[j]==1)
                        {
                            flag=1;
                            t=j;
                            break;
                        }
                    if(flag==1)
                        printf("%d
    ",t);
                    else
                        printf("none
    ");
                }
                getchar();
            }
        }
        return 0;
    }

    C - Game!

    题型:

    博弈

    题意:

    现有n个石头围成一圈

    两个人轮流拿石头,可以拿一个或连续的两个

    拿走最后石头的获胜

    题解:

    环形博弈

    对于先手只可能在他能拿石子个数的范围内取胜,否则后手赢。

    当石子个数多于两个的时候

    对手只需要拿走先手所选择石子对面的石子就一定可以获胜

    int main()
    {
        int t;
        LL n;
        scanf("%d", &t);
        while (t--) {
            scanf("%lld", &n);
            if (n <= 2) {
                printf("zbybr
    ");
            } else {
                printf("blankcqk
    ");
            }
        }
        return 0;
    }

    F - BIGZHUGOD and His Friends II

    题意:

    三个人(三个人分别为1,2,3)站在三角形的三个顶点(1站在A上,2站在B上,3站在C上)上,另有一个人站在三角形内部(可以站在内部的任意位置),之后站在顶点上的三个人按照顶点顺序开始向相邻顶点跑动(1->B,2->C,3->A),当三个人中的任意一个人跑到另一个顶点的时候,游戏结束。给定三个人跑向相邻顶点所需要的时间,问站在三角形内部的那个人能否找到一个时刻,可以挡住视线(1->C,2->A,3->B),如果有,那就输出YES和这个时刻,输出到小数点后四位。如果没有,输出NO。

    题解:

    塞瓦定理:塞瓦定理是指在△ABC内任取一点O,延长AO、BO、CO分别交对边于D、E、F,则 (BD/DC)×(CE/EA)×(AF/FB)=1

     

    通过塞瓦定理,用二分求解方程即可。如果判断循环条件为low<=high时,会超时,题意要求精确到小数点后四位,所以判断条件可以改成fabs(n)>1e-5(n为方程的结果)。

    #include<cstring>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #include<cstdio>
    #define N 1000+10
    #define inf 0x3f3f3f3f
    #define LL long long
    using namespace std;
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int t1,t2,t3,flag=0;
            double low=0,high,mid,n;
            scanf("%d%d%d",&t1,&t2,&t3);
            high=min(t1,min(t2,t3));
            do
            {
                mid=(low+high)*0.5;
                n=(t1-mid)*(t2-mid)*(t3-mid)-mid*mid*mid//方程;
                if(n>0)
                    low=mid;
                if(n<0)
                    high=mid;
                if(n==0)
                {
                    printf(".20lf
    ",n);
                    break;
                }
            }while(fabs(n)>1e-5);
            if((int)n==0)
                printf("YES %.4lf
    ",mid);
            else
                printf("NO
    ");
        }
        return 0;
    }

     H - Square Number

    题解:

    平方数:某个整数的平方;

    给定一串整数(a1,a2........an),求有多少对整数的乘积(ai*aj),使得这个乘积为平方数。

    题解:

    任何的平方数都可以分解成若干素数的偶次幂,先打表将所有素数的平方全部打出来,之后可以将每一个数先分解成若干素数的平方次幂,将分解后剩余的部分存入数组中,最后只需要找剩余部分相同的数两两匹配即可。

    代码:

    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #define N 10000000+10
    #define LL long long
    using namespace std;
    int a[N],b[N],flag[N];
    int main()
    {
        int t,num=0;
        scanf("%d",&t);
        int m=sqrt(N)+1;
        for(int i=2;i<=m;i++)
        {
            if(b[i]==0)
            {
                a[num++]=i*i;
                for(int j=i+i;j<=m;j+=i)
                    b[j]=1;
            }
        }
        while(t--)
        {
            int n,x;
            memset(flag,0,sizeof(flag));
            scanf("%d",&n);
            for(int i=0;i<n;i++)
            {
                scanf("%d",&x);
                for(int j=0;a[j]<=x&&j<=num-1;j++)
                    while(x%a[j]==0)
                    {
                        x/=a[j];
                    }
                flag[x]++;
            }
            LL ans=0;
            for(int i=1;i<N;i++)
                ans+=flag[i]*(flag[i]-1)/2;
            printf("%lld
    ",ans);
        }
        return 0;
    }

    J - Single Round Math

    题意

    给两个数n,m(0<=n,m<=10^1000),代表n个男人和m个 女人,问能否将其分成11组,使得每组男的数量等于女的数量。

    题解

    因为给的数太大,所以采用字符串处理。

    同余定理

    (a+b)%c=(a%c+b%c)%c;

    (a*b)%c=(a%c*b%c)%c;

    比如:

    846%c=((8*10+4)*10+6)%c=(((8%c*10*c)%c+4%c)%c*10%c)%c+6%c)%c;

    所以通过将字符串的每个字符转换成数字取余最后判断即可;

    代码:

    #include<stdio.h>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #define N 10000000
    using namespace std;
    char n[N],m[N];
    int main()
    {
        int t;
        scanf("%d",&t);
        getchar();
        while(t--)
        {
            int a;
            scanf("%s%s",n,m);
            getchar();
            if(strcmp(n,m)==0)
            {
                a=n[0]-48;
                for(int i=1;i<strlen(n);i++)
                {
                    a=((a%11*10%11)%11+(n[i]-48)%11)%11;
                }
                if(a==0)
                    printf("YES
    ");
                else
                    printf("NO
    ");
            }
            else
                printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    Matlab 绘制三维立体图(以地质异常体为例)
    Azure DevOps的variable group实现array和hashtable参数的传递
    Azure DevOps 利用rest api设置variable group
    Azure AADSTS7000215 其中一种问题的解决
    Power BI 实现实时更新Streaming Dataset
    AAD Service Principal获取azure user list (Microsoft Graph API)
    Matlab 沿三维任意方向切割CT图的仿真计算
    Azure Powershell script检测登陆并部署ARM Template
    Azure KeyVault设置策略和自动化添加secrets键值对
    Azure登陆的两种常见方式(user 和 service principal登陆)
  • 原文地址:https://www.cnblogs.com/aiguona/p/9211768.html
Copyright © 2011-2022 走看看