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");
}
}
}
那么今天的分享就到这里啦,继续关注后续哦。