PTA 7-1 百鸡问题扩展-N鸡问题 (20分) 7-2 编程打印空心字符菱形 (20分) 7-3 N个数求和 (20分)
程序员文章站
2022-06-07 14:39:53
...
emm 今天博主在逛PTA的时候,看到几道有意思的题目,也不是说难度多高,就,对思维有一些要求,所以就顺手拿来水博客了。
以下代码都是在pta测试过的,小伙伴们可放心食用,如果有未通过的代码,博主会注意提醒
1.7-1 百鸡问题扩展-N鸡问题 (20分)
先上代码,后分析:
#include<stdio.h>
#include<stdlib.h>
int main(){
int n,i,j,k;
scanf("%d",&n);
int cnt=0,sum=0;
for(i=0;i<=n/5;i++){
for(j=0;j<=n/3;j++){
k=n-i-j;
if(i*5+j*3+k/3==n&&k%3==0){
cnt++;
sum+=i;
}
}
}
if(cnt==0){
printf("0 -1");
}else{
printf("%d %d",cnt,sum);
}
}
- 第一个问题,题意!!!,这个题目当时确实是把博主看得眼前一蒙。顿时觉得二十年的语文都学到了太平洋里。这里建议读不懂题意的小伙伴多读几遍????
- 这里博主直接暴力遍历了,因为我不想要太花里胡哨的。这里的遍历与经典的硬币问题类似,但是,但是,但是,是有不一样的!注意题目已经说了 小鸡1元3只,而且鸡必须整只买,不能劈开买。,这是我们需要特别注意的地方。因此我们需要增加条件,这里我设k为小鸡的数目,则k%3==0,保证k一定是三的倍数,k/3正是我们买小鸡所花的钱数并且k一定等于n-i-j(注意题目有说到钱和总数都是n),这样很容易想来。用一个if即可,到这里题目已经完成,我们只需要加一点满足pta的条件即可。
7-2 编程打印空心字符菱形 (20分)
这道题目与之前打印星号组成菱形类似,但同样经过改动。难度也不一样了。
代码:
#include<stdio.h>
int main()
{
int n,i,j,m,k=1;
char ch;
scanf("%c %d",&ch,&n);
m=(n+1)/2;//如果是5的话,横向为5纵向为3.
for(i=0;i<m;i++)
{
for(j=0;j<m-i-1;j++)
printf(" ");//打印空行 第一行为2 应该是条件应该为m-i-1
printf("%c",ch);
if(i==0)
{
ch++;
printf("\n");
continue;
}
for(j=0;j<2*i-1;j++)
printf(" ");
printf("%c",ch++);//通过字符的自加来实现,这样就舍弃了字符数组的应用。
printf("\n");
}
ch=ch-2;
for(i=n-m;i>0;i--)
{
for(j=0;j<k;j++)
printf(" ");
k++;
printf("%c",ch);
for(j=0;j<2*i-3;j++)
printf(" ");
if(i==1)
{
printf("\n");
break;
}
printf("%c\n",ch--);
}
return 0;
}
- 思路要理清。我们将图案分成两部分,由上部分和下部分组成,由题可得,输入的一定是小于10的奇数,因此,我们将中间内行,与上半部分何在一块。
- 假设我们输入5那么根据古墓给出的图形,可以看到中间横行的总长为5,上半纵行总长为3。如果不确定关系的话们可以,在脑中绘制一幅图算一下,可以得到中间行长度便是n,上半纵列高度(n+1)/2。ok,关系得到,那我们用循环实现便可。
- 这道题的重点就在这里,构造空心与空行,那么这里需要小伙伴们去思考。建议在笔记本上将关系列出来。而且建议小伙伴不要列输入为5时的关系,因为并不明显。实际上我们都想的来,除了第一行变第二行需要中间增加一个空行外,其他行数变化一定都是增加两个空行。如果大家有了这个思维,我便不必再多说。
- 还有一个有意思的地方,本来博主是用的字符数组,后来转念一想,想到了字符的自加,没错,即使是字符,一样可以自加。
ASCII码
A-Z: 65-90
a-z: 97-122
0-9: 48-57
这些属于基本常识的希望小伙伴还是可以记住。这些ascii码在机内的储存使我们可以,通过自加自减的方式去改变字符。
如下:
这样的自加自减刚好符合了题意,因此,我舍弃掉了字符数组。
下半部分,实现雷同。
7-3 N个数求和 (20分)
这道题目偏重点,因为我之前刷了很多题目也没有见过类似,包括我问的大神学长,他也表示之前没有见过,然后用几分钟写了出来。。。。。。。。。。
????
难受啊。
emmm,ok回到主题。请看题目!
先上代码,第一个代码是正确答案,第二个代码仅供参考(第二个代码较为简单,但也更偏向与我们的思维模式)
#include <stdio.h>
long long digui(long long m,long long n)
{
if(m == 0)
return 0;
else
return (n == 0)?m:digui(n,m%n);
}
int main()
{
int N;
long long l;
long long a,b,c,d;
int i = 1;
scanf("%d",&N);
scanf("%lld/%lld",&a,&b);
int k=digui(a,b); //得到返回值
if(a)
{
a/=k;b/=k;
}
while(i < N)
{
scanf("%lld/%lld",&c,&d);
l=b / digui(b,d) * d;
a=a*l/ b + c *l/d;
b=l;
k = digui(a,b);
if(k != 0)
{
a = a / k;
b = b / k;
}
i++;
}
if(a && a/b == 0)
printf("%lld/%lld\n",a%b,b);
else if(a%b == 0)
printf("%lld\n",a/b);
else
printf("%lld %lld/%lld\n",a/b,a%b,b);
return 0;
}
- 首先声明这一段代码来自于网上某匿名大神,并不是博主自己写的(因为博主自己写的想尽办法,都有两个点过不去)
- 这一段代码,小伙伴们如果看不懂,请不要怀疑自己,因为博主暂时也没有理解清楚。
第二段代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int N,i,m=0,n=1;//同时进行初始化
scanf("%d",&N);//获得数量
int *p=(int*)malloc(sizeof(int)*2*N);
//开辟数组空间用来存放分子与分母,用一个2N的空间,可以避免两个数组的麻烦
for(i=1;i<N*2;i+=2)//用该循环求一个倍数
if(p[i]%n==0)
n=p[i];
else
n*=p[i];
for(i=1;i<N*2;i+=2)
{
p[i-1]=n/p[i]*p[i-1];
m+=p[i-1];
}
return 0;
}
ok,重点看思维。
1… 这段代码,已经完成了题目的大半部分任务,但我没有去补输出,已经最终对分数的化简,因为并不难,小伙伴可以自己做到。但是如果小伙伴将这段代码补充完整,在pta运行时会出现两个问题。
2… 问题需要小伙伴自己去发掘。这里我可以提醒一下,我们这样的计算,特别是在求倍数那块,会出现很大的数字,这意味着int已经不够容纳,所以实际上,我们会把int换成longlong,如果小伙伴们,现在只是需要完成pta的话,第一段代码即可,第二段,需要大家去自己思考,而且我认为我们大多数应该是偏向于使用第二段,代码,如果第二段代码补充有问题的话,可以私信博主,博主会手把手也给小伙伴演示的????