广东工业大学新生赛决赛2017解题报告

A: junior97与The Flash

数学几何题,对我这数学渣渣十分不友好。看的大佬的blog。问题的突破点在于,找到正n边形的中心点到某一顶点的距离,根据这个距离,和中心与两顶点所成交的弧度,就可以根据余弦定理算出对角线长度。下面是中点到顶点的距离的求法,根据边长为1和相邻两点与中点连线所成角用正弦或者余弦定理可以求出中点到顶点的距离。

#include<cstdio>
#include<cmath>
using namespace std;
#define pi 3.141592653
 
int t,n,m,a,b;
double sum;
 
int main()
{
     
    scanf("%d",&t);
    while(t--)
    {
        b=1;
        sum=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a);
            double x=(sin(pi/2-pi/n))/(sin(2*pi/n));
            sum+=sqrt(2*x*x*(1-cos(2*pi*(a-b)/n)));
            b=a;
        }
        printf("%.5f\n",sum);
    }
    return 0;
} 

B: 狗哥的肚子

简单的模拟

#include<cstdio>
using namespace std;
#define pi 3.14159
 
char ch;
int t,n,a,b;
double sum,maxn;
 
int main()
{
 
    scanf("%d",&t);
    while(t--)
    {
        maxn=0;
        scanf("%d",&n);
        getchar();
        while(n--)
        {
             
            scanf("%c",&ch);
            if(ch=='C')scanf("%d",&a);
            else scanf("%d%d",&a,&b);
            getchar();
             
            if(ch=='T')sum=(double)a*b/2;
            else if(ch=='R')sum=a*b;
            else sum=pi*a*a;
             
            if(sum>maxn)maxn=sum;
        }
        printf("%.2f\n",maxn);
    }
    return 0;
} 

C: 算法的魅力

等差数列+容斥原理

#include<cstdio>
using namespace std;
 
int main()
{
 
    int t,n;long long ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=((long long )5+n-(n%5))*(n/5)/2+((long long )7+n-(n%7))*(n/7)/2;
        for(long long i=35,j=1;i<=n;j++,i=35*j)ans-=i;
        printf("%lld\n",ans);
    }
    return 0;
}

D: Gakki的疑问

用字符串存每一位的数字(0到9),每一次减的策略的每一位只要非0就减1,显然,这样做减的次数为最大的一个位数。这是看大佬的blog学到的,刚开始自己想的以数字存储,每次减小于n的最大的01数,但遇到20的话,先减11,而非10,就出问题了。

#include<cstdio>
using namespace std;
 
int t,n;
int s[10],len;
int ans[10],num;
 
int pow(int num)
{
    int ret=1;
    while(num--)ret*=10;
    return ret;
}
 
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        len=0;
        num=0;
        scanf("%d",&n);
        while(n)
        {
            s[len++]=n%10;
            n/=10;
        }
        for(;;)
        {
            bool ok=1;
            for(int i=0;i<len;i++)if(s[i]){ok=0;break;}
            if(ok)break;
            int ret=0;
            for(int i=0;i<len;i++)
            {
                if(s[i])
                {
                    s[i]-=1;
                    ret+=pow(i);
                }
            }
            ans[num++]=ret;
        }
        printf("%d\n%d",num,ans[num-1]);
        for(int i=num-2;i>=0;i--)printf(" %d",ans[i]);
        putchar('\n');
    }
     
    return 0;
 } 

E: Joefery大佬的考核

又是数学几何题,花了我好久才想出来。

#include<cstdio>
using namespace std;
 
int main()
{
    int t,a,b;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&a,&b);
        printf("%d\n",a*b%10007);
    }
    return 0;
}

F: 没有题目背景的水题

裸的前缀和

#include<cstdio>
using namespace std;
 
int main()
{
    int t,a,b,n,k,num[5005];
    scanf("%d",&t);
    num[0]=0;
    while(t--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)scanf("%d",&num[i]),num[i]+=num[i-1];
        int i,j;
        bool ok=0;
        for(i=1;i<=n;i++)
        {
            for(j=i;j<=n;j++)
            {
                if(num[j]-num[i-1]==k){ok=1;break;}
            }
            if(ok)break;
        }
        printf("%d %d\n",i,j);
    }
    return 0;
}

G: 白色相簿的季节

错排,刚学到的。

#include<cstdio>
using namespace std;
 
int main()
{
    long long t,n,f[20];
    f[1]=0;
    f[2]=1;
    for(int i=3;i<=18;i++)f[i]=(i-1)*(f[i-1]+f[i-2]);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        printf("%lld\n",f[n]);
    }
    return 0;
 } 

H: 最小公倍数

因为范围很小,直接枚举这些数在1000内的公倍数,每访问到一个,标记+1,最后从1开始看哪个数标记>=k。

#include<cstdio>
#include<cstring>
using namespace std;
 
int t,n,k,x;
int cnt[1001];
 
int main()
{
     
    scanf("%d",&t);
    while(t--)
    {
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d",&n,&k);
        while(n--)
        {
             
            scanf("%d",&x);
            for(int i=x;i<=1000;i+=x)cnt[i]++;
             
        }
        int i;
        for( i=1;i<=1000;i++)if(cnt[i]>=k)break;
        printf("%d\n",i);
    }
    return 0;
} 

I: 狗哥的日常

不写了。

J: csjhl和潮汕煎蚝烙

暴力法枚举每一个符号是加还是减。

#include<cstdio>
#include<iostream>
using namespace std;
 
int main()
{
    int t,a[5],ans,sum;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        for(int i=0;i<5;i++)scanf("%d",&a[i]);
        for(int i=0;i<(1<<5);i++)
        {
            if(!(1&i))continue;
            sum=a[0];
            for(int j=1;j<5;j++)if((1<<j)&i)sum+=a[j]; else sum-=a[j];
            if(sum==24)ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
} 

K: 这题有点难

exgcd,由于不需要求x和y,所以只求gcd即可。存在xy条件是gcd(x,y)能整除c

#include<cstdio>
using namespace std;
 
void gcd(int a,int b,int& d,int& x,int& y)
{
    if(!b){d=a;x=1;y=0;}
    else
    {
        gcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
 
int main()
{
    int t,a,b,q,d,x,y,c;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&a,&b,&q);
        gcd(a,b,d,x,y); 
        for(int i=1;i<=q;i++)
        {
            scanf("%d",&c);
            if(!(c%d))puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Wen_Yongqi/article/details/83447407
今日推荐