本文作者:大家好,我是原始豌豆,欢迎来到牛客网刷题解析第六期,感谢你阅读本文欢迎评论,收藏,点赞哦。
内容专栏:这里是《牛客网在线编程》专栏,笔者用重金(时间和精力)打造,每道题目提供多种解法,从基础到拓展,希望可以帮到读者们。
写作不易:本文对每道题目提供了多种解法并加上了详细的注释,意在帮助读者锻炼思维灵活性,提高分析、解决问题的能力)。
开端
。本期讲解的是牛客网101~115题,都是基于循环打印图形的题目,难度直接拉满。BC114 圣诞树, BC115 超级圣诞树堪称循环打印图形的天花板。过于复杂,后期会单独出一篇博客进行图文详解。
题目目录
牛客网语法篇基础语法101~115题(C语言实现)
题目网址链接请点这✌️
标注*符号的题目为重点题目
本页目录跳转请点下方
BC101 翻转直角三角形图案*
BC102 带空格直角三角形图案
BC103 金字塔图案*
BC19 BC104 翻转金字塔图案 *
BC105 菱形图案*
BC106 K形图案*
BC107 箭形图案<
BC108 反斜线形图案
BC109 正斜线形图案*
BC110 X形图案*
BC111 空心正方形图案
BC112 空心三角形图案 *
BC113 数字三角形*
BC114 圣诞树***
BC115 超级圣诞树***
解法一
题目是多组输入,所以最外层采用while循环,控制多组输入,里面采用双重for循环打印倒直角三角形图形,第一层for循环控制行数,第二层for循环控制列数,每列的星号是在不断减少的。
#include
int main() {
int n, b;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n; i++) {//控制行数
for (int j = 0; j < n-i; j++) {//控制列数
printf("* ");//打印星号+空格
}
printf("\n");//每完成一行要换行
}
}
return 0;
}
解法二
与解法一相同的思路,只不过改变了循环的初始化,判断条件和调整部分
#include
int main() {
int n, b;
while (scanf("%d", &n) != EOF) {
for (int i = n; i > 0; i--) {//控制行数
for (int j = i ; j > 0; j--) {//控制列数,j随着i变动
printf("* ");//打印星号+空格
}
printf("\n");//每完成一行要换行
}
}
return 0;
}
解法一
题目是多组输入,所以最外层采用while循环,控制多组输入,里面采用for循环打印反直角三角形图形,第一层for循环控制行数,第二层和第三层for嵌套在第一层for循环内部,属于并列结构,循环打印空格空格和星号空格,每行的空格空格是在不断减少的,每行的星号星号是在不断增多的的。
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n; i++) {//一共有n层
for (int j = 1; j < n - i; j++)
printf(" ");//注意是双空格
for (int k = 0; k <= i; k++)
printf("* ");//注意是星号+空格
printf("\n");
}
}
return 0;
}
解法二
与解法一相同的思路,但是改变了i,j,k,三个循环变量的初始化,判断条件和调整部分
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = n; i > 0; i--) {//控制行数
for (int j = i; j >1; j--)//控制每行空格+空格打印的数量
printf(" ");
for (int k = n; k >= i; k--)//控制每行星号+空格打印的数量
printf("* ");
printf("\n");
}
}
return 0;
}
解法一
题目是多组输入,所以最外层采用while循环,控制多组输入,里面采用for循环打印金字塔图形,观察可以发现,金字塔图形实际上就是102题反直角三角形的变种,只不过把每次循环打印的空格数缩小一倍,其余不变。第一层for循环控制行数,第二层和第三层for嵌套在第一层for循环内部,属于并列结构,循环打印空格空格和星号空格,每行的空格空格是在不断减少的,每行的星号星号是在不断增多的。
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i <n; i++) {//外层循环,用于控制金字塔行数。对于每一个i值,都会生成一行。
for (int j = 1; j <n-i; j++)
printf(" ");//每次只打印一个空格
for (int k = 0; k <=i; k++)
printf("* ");
printf("\n");
}
}
return 0;
}
解法二
与解法一相同的思路,改变了i,j,k,三个循环变量的初始化,判断条件和调整部分
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = n; i > 0; i--) {//外层循环,用于控制金字塔行数。对于每一个i值,都会生成一行。
for (int j = i; j > 1; j--)
printf(" ");//每次只打印一个空格
for (int k = n; k >= i; k--)
printf("* ");//打印星号+空格
printf("\n");
}
}
return 0;
}
解法一
打印倒金字塔图形,观察可以发现,倒金字塔图形实际上就是上一题正金字塔图案的变种,只不过每行空格逐渐增多,每行星号逐渐减少。第一层for循环控制行数,第二层和第三层for嵌套在第一层for循环内部,属于并列结构,循环打印空格空格和星号空格,每行的空格空格是在不断增多的,每行的星号星号是在不断减少的。
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; i++) {//外层循环,用于控制金字塔行数。对于每一个i值,都会生成一行。
for (int j = 1; j < i; j++) {//每次只打印一个空格
printf(" ");
}
for (int k = 0; k <= n - i; k++)
printf("* ");//打印星号+空格
printf("\n");
}
}
return 0;
}
解法二
与解法一相同的思路,改变了i,j,k,三个循环变量的初始化,判断条件和调整部分
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = n; i >0; i--) {
for (int j = n-i; j >0; j--) {//每次只打印一个空格
printf(" ");
}
for (int k = i; k >0; k--)
printf("* ");//打印星号+空格
printf("\n");
}
}
return 0;
}
解法一
将菱形分成两部分 上部是n+1行打印 下部是n行打印。也就是正金字塔图案加倒金字塔图案
#include
int main() {
int n = 0;
while (scanf("%d", &n) != EOF) {
//将菱形分成两部分 上部是n+1行打印 下部是n行打印
for (int i = 0; i < n + 1; i++) {
for (int j = 0; j < n - i; j ++) {//上半部分空格逐渐减少
printf(" ");
}
for (int k = 0; k <= i ; k++) {//上半部分星星号+空格逐渐增多
printf("* ");
}
printf("\n");
}
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {//下半部分空格逐渐增多
printf(" ");
}
for (int k = 0; k < n - i; k++) {//下半部分星星号+空格逐渐减少
printf("* ");
}
printf("\n");
}
}
return 0;
}
解法一
将K形分成两部分 ,上部分倒着的直角三角形,下部分正着的的直角三角形,其中有一行重合部分要注意,输入的值+1就是上下三角形的边长
#include
int main() {
int n, b;
while (scanf("%d", &n) != EOF) {
n += 1;//输入的值+1就是上下三角形的边长
for (int i = 0; i < n; i++) {//上部分倒着的直角三角形
for (int j = 0 ; j < n - i; j++) {
printf("* ");
}
printf("\n");
}
for (int i = 1; i < n; i++) {//下部分正着的的直角三角形,去掉重叠的行数。
for (int j = 0 ; j <=i; j++) {
printf("* ");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int n = 0;
while (scanf("%d", &n) != EOF) {
//上一半
for (int i = 0; i <=n ; i++) { //多一行
for (int j = 0; j < n - i; j ++) {
printf(" "); //4个空格
}
for (int k = 0; k<=i ;k++) {
printf("*");
}
printf("\n");
}
//下一半
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
printf(" ");
}
for (int k = 0; k < n - i; k++) {
printf("*");
}
printf("\n");
}
}
return 0;
}
int main() {
int a, b;
while (scanf("%d", &a) != EOF) { // 注意 while 处理多个 case
for (int i = 0; i < a; i++) {
{
for (int j = 0; j <= i-1; j++)
printf(" ");
printf("*");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int a, b;
while (scanf("%d", &a) != EOF) { // 注意 while 处理多个 case
for (int i = 0; i < a; i++) {
{
for (int j = 1; j < a-i; j++)
printf(" ");
printf("*");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int a, b,n;
while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case
// 64 位输出请用 printf("%lld") to
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i+j==n-1||i==j)
printf("*");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(i==0||i==n-1||j==0||j==n-1)
printf("* ");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if(i==n-1||j==0||i==j)
printf("* ");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}
#include
int main() {
int n;
while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case
for (int i = 1; i <=n; i++) {
for (int j = 1; j <=i; j++) {
// if(i==n-1||j==0||i==j)
printf("%d ",j);
}
printf("\n");
}
}
return 0;
}
#include
int main()
{
int n = 0;
int c = 1;
while ((scanf("%d", &n)) != EOF)
{
int d = 3 * n;
for (int i = 0; i < n; i++)
{
//打印第一行
for (int j = 0; j < d - 1; j++)//先打印空格
{
printf(" ");
}
for (int k = 0; k <= i; k++)//在打印*
{
printf("* ");
}
printf("\n");
//打印第二行
for (int j = 0; j < d - 2; j++)//先打印空格
{
printf(" ");
}
for (int k = 0; k <= i; k++)//在打印*
{
printf("* * ");
}
printf("\n");
//打印第三行
for (int j = 0; j < d - 3; j++)//先打印空格
{
printf(" ");
}
for (int k = 0; k <= i; k++)//在打印*
{
printf("* * * ");
}
printf("\n");
d -= 3;
}
//树干部分打印
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3 * n - 1; j++)
{
printf(" ");
}
printf("*\n");
}
}
return 0;
}
#include
#include
int main()
{
char tree[400][800] = { 0 };//创建二维数组,以承载整个圣诞树的图案;
int n, copy, i, j;//copy代表复制的次数,i代表行,j代表列;
scanf("%d", &n);
int top_y = 3 * pow(2, n - 1) - 1;//圣诞树顶点所在的列数
//(明确指出,是为了让最基础的图形,即圣诞树的前三层能在不同n时都放对在对应的位置上)
//将n=1时的最基础的那个形状对应的图案,放入圣诞树数的第一层;
//有助于后续复制的进行(递归思想,最简单的情形)
tree[0][top_y] = '*';
tree[1][top_y - 1] = '*';
tree[1][top_y + 1] = '*';
tree[2][top_y - 2] = '*';
tree[2][top_y] = '*';
tree[2][top_y + 2] = '*';
for (copy = 1; copy < n; copy++)//代表复制的次数;
{
int range = 3 * pow(2, copy - 1);//很巧妙的设计——通过改变range,即复制的范围来实现递归——
//不断将复制得到的两个与原来的那个构成一个新的整体,再复制给下一层的两个;
//复制出右下角和左下角的两个图案:
for (i = 0; i < range; i++)
{
for (j = top_y - range + 1; j < top_y + range; j++)
{
tree[i + range][j - range] = tree[i][j];//tree[i + range][j - range]是左下角那个待复制的位置
tree[i + range][j + range] = tree[i][j];//tree[i + range][j - range]是右下角那个待复制的位置
}
}
}
//打印圣诞树主体部分(不难,只要用表达式正确表达圣诞树长宽<-找规律总结得到,即可):
for (i = 0; i < 3 * pow(2, n - 1); i++)
{
for (j = 0; j < 3 * pow(2, n); j++)
{
if ('*' == tree[i][j])
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
//打印树干的部分(简单):
for (int i = 0; i < n; i++)
{
for (int j = 0; j < top_y; j++)
{
printf(" ");
}
printf("*\n");
}
return 0;
}
总结:
本次解析的的题目难度很高,刷题需要持之以恒的努力和耐心,只有不断地练习和总结,才能提高自己的编程能力和解决问题的能力。同时,也需要注重方法,选择合适的题目、理解题目、优化算法、测试和调试、总结和反思都是非常重要的步骤。