2020级1,5班第二次上机测试补题

写在前面

感谢陈同学的协助,帮助写了问题C:打印字母Z的题解,然后这次代码会贴到题解上,下次测试题解只会有思路,不会有代码了。

不要抄代码!!!
不要抄代码!!!
不要抄代码!!!
copy真的没有意义,系统也会有查重功能的,如果到时候查出来是必须清零题数的,真的不值得。
不会可以问,但是不能不想,不去学,大部分的大学学习都是要靠自己自学的。

题解

记录时间:2020.11.02 22:53

问题 A: I still love you very much!(续)

问题A

思路

将每一行的二进制数作为字符数组循环输入,然后用循环来求得。
因为每一行的二进制数控制为8位,那么我们可以用一个循环来求得十进制的值,同时用一个字符数组保存起来。

char a[15];
scanf("%s",a);
for(j=0;j<8;j++)
{
	if(a[j]!='0')
    sum+=pow(2,7-j);
}
完整代码
#include<stdio.h>
int main()
{
    int i,j,n;
    scanf("%d",&n);
    char ans[110];
    for(i=0;i<n;i++)
    {
        int sum=0;
        char a[15];
        scanf("%s",a);
        for(j=0;j<8;j++)
        {
            if(a[j]!='0')
            sum+=pow(2,7-j);
        }
        ans[i]=sum;
    }
    for(i=0;i<n;i++)
    {
        printf("%c",ans[i]);
    }
    printf("\n");
}

问题 B: 书到用时方恨少

问题B

思路

此处主要考察了输入输出的格式符

常用格式符
格式符解释
%d十进制int型整数
%lld十进制long long 型整数
%f用来输出实数(小数或者叫浮点数),整数部分全部输出,小数超过六位的四舍五入
%lf建议以后实数全部使用%lf(double)来输入输出实数,相较于float精度更高,且大小更大
%.2lf此处2是一个例子,表示保留2位小数,注意百分号后面的点一定要加
%o八进制整数
%x十六进制整数

考试时候是不能翻书的,如果你忘记了,你可以尝试将26个字母全部试一遍,看看是哪个格式符,期末考试有时候比较喜欢考八进制和十六进制

问题C:打印字母Z

下面有请陈老师讲课

ok,are you ready?那我们正式开始了啊

那,首先我们来观察一下图形的特点,诶,不难发现,图形的第一行跟最后一行都是满满的星星,对吧。那我们是不是可以这样写

  for(i=1;i<=n;i++)
   {
       for(j=1;j<=n;j++)
       {
            if(i==1||i==n)
                printf("*");
       }
   }

诶,这个还是很好理解的对吧。程序段的意思是如果行标i为第一行或者最后一行,直接输出n个星号。

好,接下来讲一下中间行的输出,中间行的输出就有点难度了,也是这个程序的重点,仔细听啊。

好,首先,还是先来观察一下它的特点,诶,对,很显然,每一行都只有一个星号对吧,而且星号的位置在不断地向前移动,那么到这儿,我们可以联想一下,星号前面的空格数是不是也在不断减小啊,对吧。由此,我们能不能找一个与行标 i 有关的通项公式,这样便可以知道每一个星号在它所处那一行上面的列标位置对吧,如果星号的位置知道了,那空格的输出不就简单了吗,对吧,只要在星号位置前的列标上都输出空格是不是就可以了,自己思考一下。ok,在这里解释一下行标与列标的意思啊,用一个图来表示吧

1234
1****
2*
3*
4****

这图都这么明白了,应该都能理解啊

ok,接下来那我们来讲一下这个通项公式怎么得来。首先我们观察一下第二行上的星号处于哪一个列标位置,是3对吧,第三行的星号处于列标2,ok,让我们来简单的计算一下,应该是可以得到这样的一个公式:列标=总行数-行标+1;c语言式子就是:j=n-i+1;(j代表列标,i是行标,n为我们自己输入的图形的总行数)

不多bb,然我们来套一下公式看一下能不嫩得到正确的列标位置吧。第二行星号列标:j=n-i+1=4-2+1=3; ok,第二行对了,再试试第三行看能不能也正确呢,第三行星号列标:j=4-3+1=2; 诶,是不是也对了,这就是星号在中间行中的位置求法,既然知道了星号的位置,那么什么时候输出空格呢?不难看出,星号之前的所有列标位置上是不是都是空格啊,对吧,到这儿,程序是不是就已经解决了。搞懂了就很eazy。

完整代码如下

#include<stdio.h>
int main()
{
	int i,j,n,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(i==1||i==n)
				  printf("*");
				else
				  {
				      if(j==n-i+1)
				        {
				            printf("*");
				            break;
				        }
				      else 
				        printf(" ");
				  }
			}
			printf("\n");
		}
	}
}

这种图形输出,主要是找到那个与行标或者列标有关系的通项公式,相信大家都懂了,不懂得可以自己想一下或者把程序搞个数在草稿纸上运行一遍,不懂的实在不懂的也可以来问我。
ok,此题就讲到这里,咳咳,下课。

问题 D: 开门见山

思路

题意解析:这个题是给你一个大小为n的数组a,然后要求你重新排序这个数组,使得排序后数组a[i]-i的绝对值之和最大。

分析:因为i是从1~n单调递增的,那么我们想让绝对值最大,便要使得a[i]是单调递减的,大的在前小的在后,如此便使得a[i]-i的绝对值最大,那么和也为最大。

#include <stdio.h>
#include <math.h>
#define maxN 1000+10
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int ans=0,i,j,n,t,a[maxN];
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=0;i<n-1;i++)
        {
            for(j=0;j<n-i-1;j++)
            {
                if(a[j]<a[j+1])
                {
                    t=a[j];
                    a[j]=a[j+1];
                    a[j+1]=t;
                }
            }
        }
        for(i=0;i<n;i++)
        {
            ans+=abs(a[i]-(i+1));
        }
        printf("%d\n",ans);
    }
}

问题 E: 第2147483647道签到题

思路

签到题,唯一坑点便是数据范围问题。

数据类型数据类型大小
int-231 ~ 231-1 (大概109)
long long int-263~263-1(大概1018)

然后等差数列求和公式即可求解。

#include <stdio.h>
int main()
{
    long long n;
    scanf("%lld",&n);
    printf("%lld\n",(1+n)*((n+1)/2)/2);
    return 0;
}

问题 F: HPJY衣服收藏家

思路

桶排原理: 桶排序适合知道需要排序的数的范围大小,然后以此范围开一个数组,最后将每个数放到他数组中对应的位置里,就和把一个一个数放到一个一个桶里一样,所以叫桶排序。

#include <stdio.h>
int a[1000+10];
int main()
{
    int i,n;
    while(~scanf("%d",&n))
    if(n==0)printf("ÇîB\n");
    else
    {
        for(i=0;i<n;i++)
            a[i]=0;
        for(i=0; i<n; i++)
        {
            int x;
            scanf("%d",&x);
            a[x]++;
        }
        for(i=0; i<=1000; i++)
        {
            if(a[i]!=0)
            {
                printf("%d ",i);
            }
        }
        printf("\n");
    }
    return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值