第一周排位赛题解

A-SKY数
熊熊学长从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。熊熊学长非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Sky数。但是要判断这样的数还是有点麻烦啊,那么现在请你帮忙来判断任何一个十进制的四位数,是不是Sky数吧。
input
输入含有一些四位正整数,如果为0,则输入结束。
output
若n为Sky数,则输出“#n is a Sky Number.”,否则输出“#n is not a Sky Number.”。每个结果占一行。注意:#n表示所读入的n值。

分析:各进制数的各个数位上的数字之和相同,可进行取余运算,对于四位数来说,进行四次循环,便可得到各位上的数字。

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

怎么样,是不是看起来没有什么大问题,但是,我们来给它编译运行一下:
当我们想要输入两个数时:

在这里插入图片描述
并没有我们预想中的可以连续输入几个数并输出,直到0结束,问题出在哪呢?其实是因为我们将一行数据读取完就直接进行了输出,事实上,我们可以先把输入的数保存起来,经过处理后再进行输出,修改过的代码如下:


```c
#include <stdio.h>
int main()
{
	int n,x,i=0,j;
	int sum,sum1,sum2;
	int num[100];
	while(scanf("%d",&n)!=EOF&&n!=0){
		num[i++]=n;
	}
	for(j=0;j<i;j++)
	{
		n=num[j];
		x=n;
		sum=0;
		sum1=0;
		sum2=0;
		while(x!=0)
		{
			sum+=x%16;
			x=x/16;
		}
		x=n;
		while(x!=0)
		{
			sum1+=x%12;
			x=x/12;
			if(sum1>sum)
			{
				break;
			}
		}
		if(sum1==sum)
	        x=n;
		while(x!=0)
		{
			sum2+=x%10;
			x=x/10;
			if(sum2>sum)
			{
				break;
			}
		}
		if(sum2==sum)
		    printf("%d is a Sky Number.\n",n);
		else
		    printf("%d is not a Sky Number.\n",n);
	}
	return 0;
}

现在,我们再来看一下结果:在这里插入图片描述
看,是不是这样就对了。

可能会遇到类似情况的还有这样一道题:

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

古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:

1+2+4+5+10+11+20+22+44+55+110=284。

而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。

你的任务就编写一个程序,判断给定的两个数是否是亲和数
Input
输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;
Output
对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO。
Sample Input
2
220 284
100 200
Sample Output
YES
NO

我们的源代码如下:


```c
#include <stdio.h>
int main()
{
	int n,i,a,b,sum1=0,sum2=0;
	scanf("%d ",&n);
	for(i=0;i<n;i++)
    {
   	  scanf("%d %d",&a,&b);
	}
	for(i=1;i<a/2+1;i++)
	{
	  if(a%i==0)
	  sum1+=i;
	}
	for(i=1;i<b/2+1;i++)
	{
		if(b%i==0)
		sum2+=i;
	}
	if(sum1==b&&sum2==a)
	{
	    printf("YES\n");
    }
	else 
	{
		printf("NO\n");
	} 	
} 

我们看一下结果:

在这里插入图片描述
下面,我们对其进行修改:

#include <stdio.h>
int main()
{
	int n,i,a,b,sum1,sum2;
	scanf("%d",&n);
	
	int num1[n+1],num2[n+1]; 
	for(i=0;i<n;i++)
    {
    	scanf("%d%d",&num1[i],&num2[i]);
	}
	
	int x;
	for(x=0;x<n;x++){
	  a=num1[x];
	  b=num2[x];
	  sum1=sum2=0;
 	  for(i=1;i<a/2+1;i++)
	  {
	    if(a%i==0)
	    sum1+=i;
	  }
	  for(i=1;i<b/2+1;i++)
	  {
		  if(b%i==0)
		  sum2+=i;
	  }
	  if(sum1==b&&sum2==a)
	  {
	      printf("YES\n");
      }
	  else 
	  {
		  printf("NO\n");
	  }
	}
} 

我们用数组将变量的值存储起来,输出时,便可以随时取用。我们来看一下结果

在这里插入图片描述
以上两道题提醒我们,要想得到连续多组数据的结果,一定要先将输入的东西储存起来,以便最后拿来使用。

下面我们再来看一道经典的博弈论问题:

F-熊熊的尝试

熊熊学长一天在实验室里闲的没事。他想做点游戏打发一下时间。他就拉上了和他同样无聊的柴柴学长。

两位学长要玩的游戏是什么呢?很简单,它是这样定义的:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;

如果游戏的双方使用的都是最优策略,请输出哪个人能赢。
Input
输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。
Output
如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。
Sample Input
2
23 2
4 3
Sample Output
first
second

分析

对于这道题,每个人可以取1到m个石子,那么我们可以想到如果狮子的总个数是1+m的整数倍的话,那么不论第一个人取几个,第二个人都会取得胜利,假设有a(1+m)个石子,那么第一个人如果从其中取了k个石子,那么第二个人就可以取1+m-k个石子来使剩下石子的个数仍然为1+m的整数倍,这样循环往复,直到剩下最后一个1+m的时候,无论第一个人拿几个,第二个人都会将石子最终拿完。下面我们来写代码:

#include <stdio.h>
int main()
{
	int n,m;
	scanf("%d",&n);
	while(n--)
	{
		int m,n;
		scanf("%d %d",&m,&n);
		if(n%(m+1)==0)
		{
			printf("second\n");
		}
		else
		{
			printf("first\n");
		}	
	}
	return 0;
}

大家可以自己比较一下这两个代码有什么不同,一定要动手哦。


```c
#include <stdio.h>
int main()
{
	int n,i;
	scanf("%d",&n);
	int num1[n],num2[n];
	for(i=0;i<n;i++)
	{
		scanf("%d %d",&num1[i],&num2[i]);
	}
	for(i=0;i<n;i++)
	{
		if(num1[i]%(num2[i]+1)==0)
		{
			printf("second\n");
		}
		else
		{
			printf("first\n");
		}
	}

}

那么今天的分享就到这里啦,继续关注后续哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值