2020//11/30 第一次排位赛总结

第一次排位赛总结

1.Sky数

  方法一:定义一个函数,分别输入n和进制。

int sum(int n,int r)//r是要转换的进制
{
    int sum=0;
    while(n)
    {
        sum+=n%r;
        n=n/r;
    }
    return sum;
}

注意

  • 进制转换(十进制转十六进制,十进制转12进制)
  • 在每个进制下对应位数求和看三者是否相同
  • 打印结果(注意格式)

方法二(暴力法):

#include <stdio.h>
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		if(n!=0)
		{ 
		int a=n;
		int b=n;
		int c=n;
		int sum1=0;
		int sum2=0;
		int sum3=0;
		while(a)
		{
			sum1+=(a%10);
			a=a/10;
		}
		while(b)
		{
			sum2+=(b%12);
			b=b/12;
		}
		while(c)
		{
			sum3+=(c%16);
			c=c/16;
		}
		if(sum1==sum2&&sum1==sum3)
		{
			printf("%d is a Sky Number.\n",n);
		}
		else
		{
			printf("%d is not a Sky Number.\n",n);
		}
		}
		else{
			return 0;
		} 
	}
	return 0;
}

2.哥德巴赫来了可能有用吧

  • 首先是哥德巴赫猜想:大于2的偶数可以分解成两个素数之和
  • 10000以内的素数:素数筛法———用筛法求素数(可以减少时间复杂度)

在这里插入图片描述
在这里插入图片描述

#include<stdio.h>
int main()
{
   int a[10001],n;
   for(int i=2;i<=10000;i++)
   {
       a[i]=i;
   }
   for(int i=2;i<=5000;i++)
   {
   	for(int j=2*i;j<=10000;j+=i)
       {
   		a[j]=0;
   	}
   }
   while(scanf("%d",&n)!=EOF)
   {
   	if(n==0)
   		break;
   	int m=0;
   	for(int i=3;2*i<n;i++)
   	{
   		if(a[i]+a[n-i]==n)
   			m++;
   	}
   	printf("%d\n",m);
   }
   return 0;
}

3.咦!这是嘛呀!

首先了解XOR

  • 与运算(&):0&0=0;0&1=0;1&0=0;1&1=1;
  • 异或运算(xor):0^0=0; 0^1=1; 1^0=1; 1^1=0;

对于本题

  • 如果A&B等于0 那么C可以给最小的0,但是题目要特判,所以为1
  • A&B不等于0,那么就需要让C与他们共同为1的一致就好这样能得到最小值

在这里插入图片描述

typedef long long 11;
int main()
{
	int T;
	cin >> T;
	ll a,b;
	while(T--){
		cin>>a>>b;
		ll c = a&b;
		printf("%lld\n",c?c:1);
	}
	return 0;
}

4.倩姐的自我突破

此题可以投机取巧,使用暴力的方法。

样例结果
21
32
43
nn-1

5.看看就好,劝一下自己

方法一(暴力求解)

#include <stdio.h>
int main()
{
	int m;
	scanf("%d",&m);
	int i;
	int a,b;
	for(i=0;i<m;i++)
	{
		scanf("%d%d",&a,&b);
		int j,k;
		int count1=0;
		int count2=0;
		for(j=1;j<a;j++)
		{
			if(a%j==0)
			{
				count1=count1+j;
			}
		} 
		for(k=1;k<b;k++)
		{
			if(b%k==0)
			{
				count2=count2+k;
			}
		}
		if(count1==b&&count2==a)
		{
			printf("YES\n");
		}
		else
		{
			printf("NO\n");
		}
	}
	return 0;
}

方法二(约数和打表)

  • 这个就是提高了算法效率,就是他不是就是600000以内吗,我把他们的每个数的约数和求出来存在数组就好了

在这里插入图片描述

在这里插入图片描述

6.熊熊的尝试

  • 首先了解巴什博弈(只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。)
  • 思考:最多取m个,如果剩下m+1个是不是无论第一个人如何取,后手都能一次取完
  • 也就是说:无论他们前边如何拿如果n=(m+1)r+s(换句话说就是当先手拿走s个时,后手总能保证剩下的为m+1的整数倍,则后手必胜,否则先手必胜)
  • 例如:先手拿走s个,后手拿走k个保证剩下的是(m+1)的整数倍,则后手必胜,如果先手拿走s个使得剩下的为(m+1)的整数倍,则先手必胜
  • 结论:n % (m+1) == 0,后手必胜;否则先手必胜
#include <stdio.h>
int main()
{
	int c,m,n;
	scanf("%d",&c);
	while(c--)
	{
		scanf("%d%d",&m,&n);
		if(m%(n+1)==0)
		{
			printf("second\n");
		}
		else
		{
			printf("first\n");
		}
	}
	return 0;
}

7.该烂怂塔,有啥看的

思路:从下往上,保证每个局部都是最大值,即最后所得和也是最大值。

在这里插入图片描述

例如

  • 19和7选择19与2相加,得21
  • 7和10选择10与18相加,得28
#include <stdio.h>
int main()
{
	int n;
	int m;
	scanf("%d",&n);
	int a[100][100];
	int i,j,k;
	for(k=0;k<n;k++)
	{
		scanf("%d",&m);
		for(i=0;i<m;i++)
		{
			for(j=0;j<=i;j++)
			{
				scanf("%d",&a[i][j]);
			}
		}
		for(i=m-1;i>0;i--)
		{
			for(j=m-1;j>0;j--)
			{
				if(a[i][j]>=a[i][j-1])
				{
					a[i-1][j-1]=a[i-1][j-1]+a[i][j];
				}
				else
				{
					a[i-1][j-1]=a[i-1][j-1]+a[i][j-1];
				}
			}
		}
		printf("%d\n",a[0][0]);
	}
	return 0;
}

8.Tyloo的S1mple本人

暴力求解(注意:外层循环从大的开始,减少循环次数)。

#include <stdio.h>
int main()
{
	int t;
	int i,j,k,l;
	int a[10000];
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		scanf("%d",&a[i]);
	}//
	for(l=0;l<t;l++)
	{
		int s=1;
		for(i=0;7*i<=a[l];i++)
		{
			for(j=0;5*j<=a[l];j++)
			{
				for(k=0;3*k<=a[l];k++)
				{
					if(3*k+5*j+7*i==a[l])
					{
						s=0;
						break;
					}
				}
			if(3*k+5*j+7*i==a[l])
				{
					s=0;
					break;
				}		
			}
		if(3*k+5*j+7*i==a[l])
			{
				s=0;
				break;	
			}
		}
		if(s==0)
			{
			printf("%d %d %d \n",k,j,i);
			}
		else if(s==1)
			{
				printf("-1\n");
			}
}
	return 0;	
} 

9.可鞥吧

此题的思想是贪心。

#include <stdio.h>
int main()
{
	int t;
	int i,n,k;
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		int temp;
		int max=0;
		int l;
		scanf("%d%d",&n,&k);
		int j;
		int a[1000];
		for(j=0;j<n;j++)
		{
			scanf("%d",&a[j]);
		}
		for(j=0;j<n-1;j++)  //可以直接使用sort含数
		{
			for(l=0;l<n-1-j;l++)
			{
				if(a[l]<a[l+1])
				{
					temp=a[l+1];
					a[l+1]=a[l];
					a[l]=temp; 
				}
			}
		}
		for(j=0;j<=k;j++)
		{
			max=max+a[j];
		}
		if(k==0)   //注意考虑k=0的情况
		{
			printf("%lld\n",a[n-1]-a[0]);
		}
		else
		{
			printf("%lld\n",max);
		}
	}
	return 0;
}

10.最后是啥呢

  • 首先明确最后最小值的结果一定是2
#include <stdio.h>
int main()
{
	int m,n;
	scanf("%d",&m);
	int a[200000];
	for(int i=0;i<m;i++)
	{
		int k=1;
	    int q=3;
		scanf("%d",&n);
		for(int j=0;j<n;j++)
		{
			a[j]=k++;
		}
		printf("2\n");
		for(int j=0;j<n-1;j++)
		{
			printf("%d %d\n",a[n-q+1],a[n-q+2]);
			if((a[n-q+1]+a[n-q+2])%2!=0)
			{
				a[n-q+1]=((a[n-q+1]+a[n-q+2])/2)+1;
			}
			else
			{
				a[n-q+1]=((a[n-q+1]+a[n-q+2])/2);
			}
				q++;
		} 
	}
	return 0;
}
		
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值