2017广东工业大学ACM新生杯决赛

野生题解。

Problem A: junior97与The Flash

思路:这题精度有点苛刻了,导致姿势不太好的小伙伴都过不了。我的做法是先求出中心到顶点的距离(即外接圆半径,因为ax和角xoa已知),那么求距离直接用余弦定理就OK。

2017广东工业大学ACM新生杯决赛_第1张图片

# include 
using namespace std;
const double pi = 3.141592653;
int n, m, a[1003];
double len;
double cal(int x, int y)
{
    int dis = abs(x-y);
    double ang = 360.0/n*dis*pi/180;
    double res = sqrt(2*len*len*(1-cos(ang)));
    return res;

}
int main()
{
    //freopen("3.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        double tmp = 360.0/n/2*pi/180;
        len = 1/(2*sin(tmp));
        for(int i=0; i

Problem B: 狗哥的肚子

思路:直接计算取最大的面积即可。

# include 
using namespace std;
const double pi = 3.14159;
int main()
{
    int T, n, x ,y;
    char c;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        double imax = 0;
        while(n--)
        {
            getchar();
            scanf("%c",&c);
            if(c == 'T')
            {
                scanf("%d%d",&x,&y);
                imax = max(imax, x*y*1.0/2);
            }
            else if(c == 'R')
            {
                scanf("%d%d",&x,&y);
                imax = max(imax, 1.0*x*y);
            }
            else
            {
                scanf("%d",&x);
                imax = max(imax, pi*x*x);
            }
        }
        printf("%.2f\n",imax);
    }
    return 0;
}

Problem C: 没有题目背景的水题

思路:暴力O(n*n)可以过的。

# include 
using namespace std;
typedef long long LL;
const double pi = 3.14159;
int a[5003];
int main()
{
    int T, n, k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; ++i) scanf("%d",&a[i]);
        bool flag = 1;
        for(int i=1; i<=n&&flag; ++i)
        {
            int sum = 0;
            for(int j=i; j<=n&&flag; ++j)
            {
                sum += a[j];
                if(sum == k)
                {
                    printf("%d %d\n",i,j);
                    flag = 0;
                }
            }
        }
    }
    return 0;
}

Problem D: Gakki的疑问


思路:个数最少和字典序最小,显然是贪心每次选做多1的,最后排下序输出即可。

# include 
using namespace std;
int a[13], b[10]={0,1,10,100,1000,10000,100000,1000000};
int main()
{
    int T, n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int cnt = 0;
        while(n)
        {
            int x = n, k = 0;
            for(int i=1; i<=6&&x; ++i)
            {
                int y = x%10;
                if(y>0)
                {
                    n -= b[i];
                    k = k+b[i];
                }
                x /= 10;
            }
            a[cnt++] = k;
        }
        sort(a, a+cnt);
        printf("%d\n",cnt);
        for(int i=0; i

Problem E: Joefery大佬的考核

思路:连接边DG就发现三角形ADG的面积均为正方形和矩形面积的一半(以AD为底和以AG为底),那么a*b%10007就是答案。这些题其实看到答案是整数的话可以猜一下公式。

# include 
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;
}

Problem F: 算法的魅力


思路:简单的容斥原理,先算5倍数的和,加上7倍数的和,减去5和7的最小公倍数(35)的倍数的和,就是等差数列求和。
# include 
using namespace std;
typedef long long LL;
LL n;
LL cal(LL x)
{
    LL r = n/x*x;//<=n里最大的能被x整除的数。
    LL res = (x+r)*((r-x)/x+1)/2;
    return res;
}
int main()
{
    int T;

    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&n);
        LL ans = cal(5)+cal(7)-cal(35);
        printf("%lld\n",ans);
    }
    return 0;
}

Problem G: 白色相簿的季节

思路:就是错排问题,用递推式。

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

Problem H: 最小公倍数

思路:这题内榜AC率很尴尬。题面已经暗示了 公有的倍数中最小的一个 ,直接从小到大枚举答案X,如果X能被>=K个数整除,它肯定就是最小公倍数了,答案范围很亲民,都不用线筛那样打表了。

# include 
# include 
using namespace std;
int a[103];
int main()
{
    int T, n, k;
    scanf("%d",&T);
    while(T--)
    {
        int ans;
        scanf("%d%d",&n,&k);
        for(int i=0; i= k)
            {
                ans = i;
                break;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

Problem I: 狗哥的日常

思路:......

# include 
using namespace std;
int main()
{
    int T, n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        while(n--)
            puts("Rua");
        if(T) puts("");
    }
    return 0;
}

Problem J: csjhl和潮汕煎蚝烙

思路:实在不会枚举所有情况都能过了。深搜一下即可。

# include 
using namespace std;
int a[6], ans;
void dfs(int num, int id)
{
    if(id == 6)
    {
        ans += num==24;
        return;
    }
    dfs(num+a[id], id+1);
    dfs(num-a[id], id+1);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans = 0;
        for(int i=1; i<=5; ++i) scanf("%d",&a[i]);
        dfs(a[1], 2);
        printf("%d\n",ans);
    }
    return 0;
}

Problem K: 这题有点难

思路:c可以整除a和b的最大公因数就行了,具体搜索“扩展欧几里得”相关知识。

# include 
using namespace std;
int main()
{
    int T, a, b, c, q;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&a,&b,&q);
        int g = __gcd(a,b);
        while(q--)
        {
            scanf("%d",&c);
            printf(c%g==0?"Yes\n":"No\n");
        }
    }
    return 0;
}


你可能感兴趣的:(笔试题目/套题)