牛客网编程初学者入门训练1

BC2 我是大V

描述

每个人都想成为大V (VIP:Very Important Person),但要一点一点积累才行,先从小v做起。要求输出由小写字母v组成的大V。

输入描述:

输出描述:

在这里插入图片描述

备注:

换行使用转义字符‘\n’

(第一行两个v之间隔了三个空格,第二行两个v之间隔了一个空格,第三行v前有两个空格,第二行第一个v前有一个空格)

内心想法:

一眼看去就想直接暴力输出了,毕竟是一道很简单的题,也没啥要求······

于是把以下代码交了赶下一题

#include<iostream>
using namespace std;
int main()
{
    cout<<"v   v\n v v\n  v"<<endl;
}

但转念一想,要是这个行数很大,或者是自己规定行数的,那不就寄了吗······

所以还是得搞个通法,至少有点底气······

以此题输出三行为例观察一下这种形式在这里插入图片描述

不难发现,每一行(除最后一行外)v是对称的,最后一行的v居中,而且只看前三列的正方形,v恰好在对角线输出,看后三列也一样,于是就有了下面的解法(忽略题目备注):

#include<iostream>
using namespace std;
int main()
{
    for(int i = 0;i < 3;i++)
    {
        for(int j = 0;j < 5;j++)
        {
            if(i == j || j == 4 - i)
            {
                cout<<"v";
            }
            else
            {
                cout<<" ";
            }
        }
        cout<<endl;
    }
}

外层循环条件表达式中的 3 是输出的行数,内层循环条件表达式中的 5 是第一行v和空格的个数和,if语句判断条件中的 4 是 5-1 ,因为我们把 j 定义为 0 了,所以这个数不是5。(细索之下我们发现如果要求输出 n 行,那么第一行v和空格的个数和满足 2n-1 ,2n-1 是个奇数,减去两个v的 2n-3 还是奇数,所以第一行两个v之间的空格数只能为奇数。)

如果这道题要求不定多次且完全随机输入行数,我们大可把这个循环写成一个函数,按照具体要求加上一些判断条件,然后在主函数中用while循环之类的引用即可。

BC7 缩短二进制

描述

我们处理的整数通常用十进制表示,在计算机内存中是以二进制补码形式存储,但通常二进制表示的整数比较长,为了便于在程序设计过程中理解和处理数据,通常采用八进制和十六进制,缩短了二进制补码表示的整数,但保持了二进制数的表达特点。请输出十进制整数1234对应的八进制和十六进制。

输入描述:

输出描述:

十进制整数1234对应的八进制和十六进制(字母大写),用空格分开,并且要求,在八进制前显示前导0,在十六进制数前显示前导0X。

备注:

printf可以使用使用格式控制串“%o”、“%X”分别输出八进制整数和十六进制整数,并使用修饰符“#”控制前导显示

内心想法:

看到这道题有点尴尬,一是因为发现自己好像几乎没做过进制转换,虽然这道题只是很基础的那种,还是让我懵了一下;二是我不习惯用 printf()函数,决定还是用cout格式输出。有时间还是得写一下各个进制转换的函数锻炼一下。

这道题要求了强制输出整数的基数(八进制以0打头,十六进制以0x打头),还要求了十六进制的字母要大写,所以要用到 cout.setf() 函数,而且格式标志要选 ios::showbase 和 ios::uppercase 。

关于 cout.setf() 函数以及C++中输入输出的知识,可以参考这两篇博客,写的很详细:

C++中cout.setf()函数

C++输入cout与输出cin

接下来的代码实现就比较简单了:

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int n = 1234;
    cout.setf(ios::showbase | ios::uppercase);
    cout<<oct<<n<<" "<<hex<<n;
}

这里要注意两点:

一是头文件。使用 cout.setf() 函数和控制符 oct 、hex ,要包含这个头文件:

#include<iomanip>

当然,如果想小偷个懒,可以直接祭上万能头文件:

#include <bits/stdc++.h>

但是呢,可能会有某些oj会不支持这个头文件,可能有些大型比赛会禁用,如果实在忘了或者赶时间可以用下,但本人还在学习的初期,还是先记一下。

关于这点可以看看这篇博客:

万能头文件#include“bits/stdc++.h”

二是设置格式状态的格式标志。用 cout.setf() 函数设置格式状态时,可以包含两个或以上的格式标志,由于这些格式标志在ios类中被定义为枚举值,每一个格式标志以一个二进位代表,因此可以用位或运算符“|”组合多个格式标志,不必分成几行写。(在visual studio中用逗号隔开也可以,但在牛客网会WA,暂时还不太清楚)

BC8 十六进制转十进制

描述

BoBo写了一个十六进制整数ABCDEF,他问KiKi对应的十进制整数是多少。

输入描述:

输出描述:

十六进制整数ABCDEF对应的十进制整数,所占域宽为15。

备注:

printf可以使用使用格式控制串“%md”输出域宽为m的十进制整数。

内心想法:

老规矩,还是忽略备注继续用cout输出格式。

这题就考两个知识点:

一是C++中十六进制的表示方法,要用前缀“0x”和后面的十六进制数据,即 ABCDEF 要表示成 0xABCDEF 。

二是规定了输出值所占的域宽为15。规定域宽要用到参数化的流操纵符 setw() ,这个流操纵符在这个头文件中:

#include<iomanip>

剩下的代码实现就很简单了:

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    int n = 0xABCDEF;
    cout<<setw(15)<<dec<<n<<endl;
}

BC9 printf的返回值

描述

KiKi写了一个输出“Hello world!”的程序,BoBo老师告诉他printf函数有返回值,你能帮他写个程序输出printf(“Hello world!”)的返回值吗?

输入描述:

输出描述:

包括两行:
第一行为“Hello world!”
第二行为printf(“Hello world!”)调用后的返回值。

内心想法:

看到这道题就知道还是逃不过 printf() ,但是这个不是关键,关键是发现自己一直没注意过 printf() 函数的返回值!所以我们试着把输出的内容赋给一个整型,再输出这个整型看看。

#include<stdio.h>
#include<iostream>
using namespace std;
int main()
{
    int n = printf("Hello world!");
    printf("\n");
    printf("%d",n);
    return 0;
}

值得注意的有两点:

一是头文件。printf() 函数是包含在

二是第 6 行的赋值方式。这样既实现了一次输出,又记录了 printf() 的返回值。(第 8 行的 %d 表示的是规定以整型输出。)

在本地IDE上运行这段代码我们发现第二行输出结果是 12 ,恰好是 Hello world! 的字符串长度!于是回头看我们就能发现,在第 6 行的输出中万万不能加上 \n ,这会导致返回值比正确的返回值多 1 ,应该单独换行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lum0s!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值