第一次排位赛题目总结

D—倩姐的自我突破
  • 寻找样例规律

题目链接

#include <stdio.h>
int main()
{
    long long int n, ans;
    scanf("%lld", &n);
    while (n--)
    {
        scanf("%lld", &ans);
        printf("%lld\n", ans - 1);
    }
    return 0;
}

F—熊熊的尝试

题目链接

  • 博弈论——巴什博弈(只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。)
  • 最多取m个,如果剩下m+1个是不是无论第一个人如何取,后手都能一次取完
  • 即:n % (m+1) == 0,后手必胜;否则先手必胜
int main()
{
	int N,n,m,i;
	scanf("%d",&N);
	for(i=0;i<N;i++)
	{
		scanf("%d %d",&n,&m);
		if(n<=m)
		{
			printf("first\n");
		}	
		else if(n%(m+1)!=0)
		{
			printf("first\n");
		}
		else
		{
			printf("second\n");
		}	
	}
	return 0;
}

H—Tyloo的S1mple本人

题目链接

  • 任意输出一组满足3a+5b+7*c==n的a、b、c
  • 优化:外层循环从7开始可减少时间复杂度
  • 优化:每次无需+1 +=3/5/7可减少时间复杂度
int main()
{
	int N,n,i,a,A,b,B,c,C,flag;
	scanf("%d",&N);
	for(i=0;i<N;i++)
	{
		scanf("%d",&n);
		A = B = C = flag = 0;
		for(a=0;a<=n/3;a++)
		{
			for(b=0;b<=n/5;b++)
			{
				for(c=0;c<=n/7;c++)
				{
					int sum = a*3+b*5+c*7;
					if(sum==n)
					{
						flag++;
						A = a;
						B = b;
						C = c;
					}
					if(flag!=0)
					{
						a = b = c = n;
					}
				}
			}
		}
		if(A!=0||B!=0||C!=0){
			printf("%d %d %d\n",A,B,C);
		} else {
			printf("-1\n");
		}	
	}
	return 0;
}

G—该烂怂塔,有啥看的

题目链接

  • DP(动态规划)算法
  • 逆向思维,从下向上找到最优解

在这里插入图片描述

#include <stdio.h>
int max(int a,int b)
{
	if(a>=b)
	{
		return a;
	}
	else
	{
		return b;
	}
}
int main()
{
	int C;
	scanf("%d",&C);
	while(C--)
	{
		int N,i,j;
		int dp[100][100]; 
		scanf("%d",&N);
		for(i=0;i<N;i++)
		{
			for(j=0;j<=i;j++)
			{
				scanf("%d",&dp[i][j]);
			}
		}
		for(i=N-2;i>=0;i--)
		{
			for(j=0;j<=i;j++)
			{
				dp[i][j] += max(dp[i+1][j],dp[i+1][j+1]);
			}
		}
		printf("%d\n",dp[0][0]);
	} 
	return 0;
}

E—看看就好,劝一下自己

题目链接

  • 法1:暴力求解
  • 法2:根据题意0 <= A,B <= 600000,故可建立一个数组存储该范围内的约数和表,之后直接调用即可(代码实现如下,以前300个数为例)
int main()
{
    int n,a,b,i,j,s;
    int num[300] = {0,0,0};
	for(i=4;i<299;i++)
	{
		s = 0;
	 	for(j=1;j<i;j++)
	 	{
	 		if(i%j == 0)
			{
				s += j;	
			} 
		}
		num[i-1] = s;
	}
    scanf("%d",&n);
    while(n--)
        {
            scanf("%d%d",&a,&b);
            if(num[a-1]==b && num[b-1]==a)
                 printf("YES\n");
            else
                 printf("NO\n");
        }
    return 0;   
}

I—可鞥吧

题目链接

  • 暴力求解 每次将次多的桶倒入最多的桶里
#include <stdio.h>
#include <algorithm>
int main(void)
{
    long long int t, n, k, sum;
    scanf("%lld", &t);
    long long int a[200000];
    long long int b[1000];
    int i,j;
    for (i=0;i<t;i++)
    {
        sum = 0;
        scanf("%lld %lld",&n,&k);
        for (j=0;j<n;j++)
        {
            scanf("%lld", &a[j]);
        }
        std::sort(a,a+n);
        sum = a[n-1];
        for (j=0;j<k;j++)
        {
            sum += a[n-j-2];
        }
        if (!k)
        {
            b[i] = sum - a[0];
        }
        else
        {
            b[i] = sum;
        }
    }
    for (i=0;i<t;i++)
    {
        printf("%lld\n",b[i]);
    }
    return 0;
}

A—Sky数

题目链接

  • 进制转换的代码实现(10>16 10>12)
  • 思路:写一个进制转换的函数,输入时调用即可
#include <stdio.h>
int swap(int n1, int n2)
{
	int sum = 0;
	while(n1 != 0)
	{
		sum += n1%n2;
		n1 /= n2;
	}
	return sum;
}

int main()
{
	int n,num;
	while(1)
	{
		scanf("%d",&n);
		if(n == 0)
		{
			break;
		}
		num = n;
		int ten = swap(n,10);
		int twelve = swap(n,12);
		int sixteen = swap(n,16);
		if(twelve == sixteen && ten == twelve)
		{
			printf("%d is a Sky Number.\n",num);
		}
		else
		{
			printf("%d is not a Sky Number.\n",num);
		}
	}
	return 0;
} 

B—哥德巴赫来了可能有用吧

题目链接

  • 10000以内素数:素数筛法——用筛法求素数
    即若一个数为素数,则其倍数一定不为素数。排除它的倍数可提高代码效率。
  • 打表法将范围内的素数列出
#include <stdio.h>
int pend(int a)
{
    for (int i=2;i*i<=a;i++)
    {
        if (!(a%i))
        {
            if (i!=a)
            {
                return 0;
            }
        }
    }
    return 1;
}
int main(void)
{
    int a[501];
    int count=0,n,b,c,ans;
    while(1)
	{
		scanf("%d",&n);
		if(n == 0)
		{
			break;
		}
		b = 3;
		ans = 0;
        for (int j=3;j<n/2;j++)
        {
            if (pend(j) && pend(n-j) && b!=c)
            {
                ans++;
            }
        }
        printf("%d\n",ans);
	} 
    return 0;
}

C—咦!这是嘛呀!

题目链接

  • 异或运算与和与运算
  • 真值表如下
    真值表
    由上表知,若要使((A ^ C) & (B ^ C))最小,则只需 C = A & B ,若C = 0,则输出1,反之输出C。
#include <stdio.h>
int main()
{
    int n;
    scanf("%d", &n);
    long long a[1000][2];
    for (int i = 0; i < n; i++)
    {
        scanf("%lld%lld", &a[i][0], &a[i][1]);
    }
    for (int i = 0; i < n; i++)
    {
        long long int c = a[i][0] & a[i][1];
        if (!c)
            printf("1\n");
        else
            printf("%lld\n", c);
    }
    return 0;
}

J题—最后是啥呢!

题目链接

  • 题意:从1到n的数列,让后你每次操作取出a、b放入 ,然后n-1次后就会剩下一个数
  • 需要考虑如何操作才能使最后的数最小,最小是多少
  • 需明确你不论如何操作最小值都会是2
  • 每次从大到小取数
#include <stdio.h>
int a[1000];
int c[2000000];
int main()
{
    int n,i,j;
    scanf("%d", &n);
    for (i=0;i<n;i++)
    {
        scanf("%d", &a[i]);
    }
    for (i=0;i<n;i++)
    {
        int b = a[i];
        for (j=0;j<b;j++)
        {
            c[j] = j + 1;
        }
        printf("2\n");
        for (j=0;j<b-1;j++)
        {
            printf("%d %d\n", c[b-j-2], c[b-j-1]);
            c[b-j-2] = (c[b-j-2] + c[b-j-1])/2 + (c[b-j-2] + c[b-j-1])%2;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值