首页 > 试题广场 >

打印沙漏(20)

[编程题]打印沙漏(20)
  • 热度指数:20468 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印

*****
 ***
  *
 ***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递
增;首尾符号数相等。

给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。

输入描述:
输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。


输出描述:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
示例1

输入

19 *

输出

*****
 ***
  *
 ***
*****
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

int main ()
{
	int N;
	char flag;
	cin>>N>>flag;

	int count = 1, nleft;
	while (2*count*count-1 <= N) {
		count++;
	}
	count--;
	nleft = N - 2*count*count +1;
	for(int i=count; i>=1; i--)  {
		cout<<setfill(' ')<<setw(count-i)<<"";
		cout<<setfill(flag)<<setw(2*i-1)<<""<<endl;
	}
	for(int i=2; i<=count; i++) {
		cout<<setfill(' ')<<setw(count-i)<<"";
		cout<<setfill(flag)<<setw(2*i-1)<<""<<endl;
	}
    cout<<nleft;

	return 0;
}

发表于 2015-09-19 15:12:32 回复(1)
#include<iostream>
using namespace std;
int f(int n)
{
    int k=1;
    while((k*k*2-1)<=n)
    {
        k++;
    }
    return k-1;
}
int main()
{
    int N;
    char s;
    while(cin>>N>>s)
    {
        int y=2*f(N)-1;
        for(int i=0;i<y;i++)
        {
            for(int j=0;j<y;j++)
            {
                if(((i<=j)&&(i<=-j+y-1))||((i>=j)&&(i>=-j+y-1)))
                {
                    cout<<s;
                }
                else
                {
                    cout<<' ';
                }
            }
            cout<<endl;
        }
        cout<<N-2*f(N)*f(N)+1;
    }
}
发表于 2018-09-05 22:48:08 回复(0)
//坑处在于右侧不需要打印空格。。总是格式不对
#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n;char c;
    while(cin>>n>>c)
    {
        int i=1;
        while(2*i*i-1<=n)
            i++;
        int temp=n-(2*(i-1)*(i-1)-1);//剩下的字符数;
        i--;
        for(int j=i;j>0;j--)
            cout<<string(i-j,' ')<<string(2*j-1,c)<<endl;
        for(int j=2;j<=i;j++)
            cout<<string(i-j,' ')<<string(2*j-1,c)<<endl;
        cout<<temp<<endl;
    }
}
//这个应该比较简洁了吧

发表于 2018-05-14 23:06:13 回复(1)

python解法 非常之简单

直接把每层的数量求出来放到一个数组里面,遍历这个数组打印就可以了。

a = input().split()
# totalCount是符号的数量(一点一点的减掉) symbol是输入的符号(如*)
totalCount, symbol = int(a[0]) - 1, a[1]
# currentLevelCount是当前层符号的数量(从1,3,5递增)。symbolArray是每层符号的数量。
currentLevelCount, symbolArray = 3, [1]
# 每当可以再加一层,便进行计算。
while totalCount > currentLevelCount * 2:
    totalCount = totalCount - currentLevelCount * 2
    symbolArray.append(currentLevelCount)
    symbolArray.insert(0, currentLevelCount)
    currentLevelCount += 2
for i in symbolArray:
    print(" " * ((symbolArray[0] - i) // 2) + symbol * i)

print(totalCount)
发表于 2018-02-07 11:43:28 回复(1)
分上下两部分打印 最重要的是找行数  与空格数 与字符数之间的关系
#include<iostream>
using namespace std;
int main(){
    int num,n=0;
    char flag;
    cin>>num>>flag;
    int sum=-1;
    while(sum<=num){
        n++;
        sum=2*n*n-1;
    }
    for(int i=n-1;i>0;i--){//输出上半部分
        for(int j=n-1-i;j>0;j--)
            cout<<" ";
        for(int j=2*i-1;j>0;j--)
            cout<<flag;
        cout<<endl;
    }
    for(int i=2;i<=n-1;i++){//输出下半部分
        for(int j=n-1-i;j>0;j--)
            cout<<" ";
        for(int j=2*i-1;j>0;j--)
            cout<<flag;
         cout<<endl;
    }
    cout<<num-2*(n-1)*(n-1)+1<<endl;
    return 0;
}

发表于 2017-04-20 21:31:27 回复(0)
#include <iostream>
#include <cstdio>
using namespace std;

int main(){
    int n,t=1;  cin>>n;  
	char c;     cin>>c;//需要打印的字符 
    int i=n-1,j=1;
	while(i>j*2){ 	//算出需要打印的最多的一行字符数 
		j+=2;		//j 最多的字符的个数 
		i=i-j*2;	//i 输出沙漏后剩的字符数			
	} 
	if(j==1){		// 只需要输出一行时的处理 
		cout<<c<<endl;
		cout<<i;
		return 0;
	}else{
		for(int m=j;m>0;m-=2){ //输出上部分的沙漏 
			int f=t; 								
			while(--f) cout<<" ";
			t++;  //t、f控制输出的空格数 
			for(int n=0;n<m;++n)   // m表示输出的字符数 
				cout<<c;			
		cout<<endl;
		}	
			
		for(int m=3;m<=j;m+=2){//输出下部分的沙漏 
			t--;
			int f=t-1;								
			while(--f) cout<<" ";
			for(int n=0;n<m;++n)
				cout<<c;	
		cout<<endl;
		}
	}	
	cout<<i;
	return 0;	
}

发表于 2022-04-07 11:08:00 回复(0)
给个短点的Python代码,纯模拟
计算能打多少行符号,然后存入列表
while True:
    try:
        n, flag = map(str, input().split())
        S = 1
        a = 1
        stores = [flag]
        while S + (a + 2) * 2 < int(n):
            stores.append(stores[-1] + flag * 2)
            a += 2
            S += a * 2
        spaces = 0
        for i in stores[::-1]:
            print(' ' * spaces, end='')
            spaces += 1
            print(i)
        spaces -= 1
        for i in stores[1:]:
            spaces -= 1
            print(' ' * spaces, end='')
            print(i)
        print(int(n) - S)
    except:
        break


编辑于 2020-04-16 19:47:13 回复(0)
提交时间:2020-04-16 语言:C++ 运行时间:3ms 占用内存:492K 状态:答案正确
#include<iostream> using namespace std; int main() {     int n,a,m,rest=0;//个数,能用到的个数,行数 ,剩余个数     char c;     cin>>n>>c;     for(int i=1;i<100;i++)     {         if(2*i*i-1>n)//超出了总个数         {             a=2*(i-1)*(i-1)-1;//取上一情况,确定能用到的符号个数             m=2*i-3;//总行数             rest=n-a;             break;         }         else if(2*i*i-1==n)//恰好相等         {             a=n;             m=2*i-1;             break;         }     }     for(int i=0;i<m;i++)     {         for(int j=0;j<m;j++)         {             if(i<(m+1)/2)//上半部分(包括了中间一行)             {                 if(j>=i&&j<=m-1-i) cout<<c;                 else cout<<' ';             }             else//下半部分             {                 if(j>=m-1-i&&j<=i) cout<<c;                 else cout<<' ';             }         }         cout<<endl;     }     cout<<rest<<endl;     return 0; }
我是按照比较好理解的方式写的,可能比较长和繁琐……萌新一枚,写的不好,大家见谅哈。。
c++
思路解析:
1.利用等差数列求出最大行数,从1开始遍历,一旦超过总个数就回到上一个位置。
2.将沙漏分为两部分,上半部分(包括中间一行)和下半部分。上半部分越往下字符数目减少,直到减为1,下半部分越往下字符越多。分界之处和总行数以及当前所在行数有关,且上下两部分分界处交换位置。
3.打印即可。
编辑于 2020-04-16 11:22:26 回复(0)

思路,找到*总数、和最外层*的个数就可以了。

#include<iostream>
using namespace std;
int main() {
    int N,i,sum=1;
    char c;
    cin>>N>>c; 
    for(i=3; sum<=N; i+=2) {//试图找到*的总数,以及最外层*的个数 
        sum+=2*i;
    }
    //补偿 
    i-=2;
    sum-=2*i;
    i-=2;
    int spc,star;
    for(int j=i; j>=1; j-=2) {//打印上半部分 ,包括一个* 
        spc=(i-j)/2;
        while(spc--)cout<<" ";
        star=j;
        while(star--)cout<<c;
        cout<<endl;
    }
    for(int j=3; j<=i; j+=2) {//打印下半部分,不包括一个* 
        spc=(i-j)/2;
        while(spc--)cout<<" ";
        star=j;
        while(star--)cout<<c;
        cout<<endl;
    }
    cout<<N-sum;
    return 0;
}
编辑于 2020-01-30 23:21:43 回复(0)
#include<iostream>
#include<cmath>
using namespace std;

int main()
{     int N;     char c;     cin >> N>>c;     //cin >> c;     if (N == 1)     {         cout << c << endl;         cout << "0" << endl;     }              else     {         int layer = (int)sqrt(N / 2);         int t = N - 2 * layer*layer + 1;         for (int i = layer - 1;i > -layer;i--)         {             for (int j = 0;j < abs(abs(i) - (layer-1));j++)                 cout << " ";             for (int z = 0;z < 2 * abs(i) + 1;z++)                 cout << c;             cout << endl;         }         //cout << endl;         cout << t << endl;     }     system("pause");     return 0;
}

发表于 2019-01-17 15:48:44 回复(1)
#python,打印了后面的空格,通过。
try:
    while True:
        tempInput = input().split()
        num = int(tempInput[0])
        sign = tempInput[1]
        maxLen = 1
        cost = 1
        remaining = 0
        while num > cost:     #找出最大长度和剩余个数
            if num>cost+2*(maxLen+2):
                maxLen+=2
                cost+=2*maxLen
            else:
                remaining = num-cost
                break
        for i in range(maxLen//2+1):      #打印到一颗“*”时停,注意边界
            print(" "*i,end="")     #前面的空格数
            print(sign*(maxLen-i*2),end="")  #中间的“*”数
            print(" "*i)                 #我打印了后面的空格,是能通过的
        for i in range(maxLen//2-1,-1,-1): #打印剩下的,符号递增的
            print(" " * i, end="")
            print(sign * (maxLen - i * 2), end="")
            print(" " * i)
        print(remaining)
except Exception:
    pass

编辑于 2018-09-21 18:03:10 回复(0)
输出的字符后面不能带空格。
发表于 2018-02-26 10:12:00 回复(0)
注意一点:右侧不满一行的不需要空格!!!
import java.util.*;

public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int N = sc.nextInt();
            String c = sc.next();
            
            int i = 0;
            for(; i < 22; i ++){
                if((2*i*i+4*i+1 <= N) && (2*(i+1)*(i+1)+4*(i+1)+1) > N)
                   break;
            }
            int n = i;
            for(;i > 0; i--){
                for(int j = 0; j < n-i; j++)
                    System.out.print(" ");
                for(int j = 0; j < 2*i+1; j++)
                    System.out.print(c);
                System.out.println();
            }
            for(;i <= n; i++){
                for(int j = 0; j < n-i; j++)
                    System.out.print(" ");
                for(int j = 0; j < 2*i+1; j++)
                    System.out.print(c);
                System.out.println();
            }
            System.out.println(N-2*n*n-4*n-1);
        }
        sc.close();
    }
}

发表于 2017-12-13 12:00:31 回复(2)

格式出错什么鬼? -。-

#include <stdio.h>
#include <math.h>
void print(int i, int k, char ch){
  int j;
  for (j = k; j > 0; j--)
   putchar(' ');
  for (j = 2 * i - 1; j > 0; j--)
   putchar(ch);
  for (j = k; j > 0; j--)
   putchar(' ');
  putchar('\n');
}
int main(){
 int N, col, i, k;
 char ch;
 scanf("%d %c", &N, &ch);
 col = sqrt((N + 1) / 2.0);
 for (i = col, k = 0; i > 1; i--, k++)
  print(i, k, ch);
 for (i = 1; i <= col; i++, k--)
  print(i, k, ch);
 printf("%d", N - 2 * col * col + 1);
 return 0;
}

发表于 2017-08-09 14:01:58 回复(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
importjava.util.Scanner;
 
publicclassMain {
 
    publicstaticvoidmain(String[] args) {
        Scanner in = newScanner(System.in);
        intN  = in.nextInt();
        charsymbol = in.next().toCharArray()[0];
        int[] max = measure(N);
        for(inti=max[0];i>=-max[0];i--){
            intk = 2*Math.abs(i)+1;
            intkk = max[0]-Math.abs(i);
            while(--kk>=0)
                System.out.print(" ");
            while(--k>=0)
            System.out.print(symbol);
            System.out.println();
             
        }
        System.out.print(max[1]);
         
    }
    staticint[] measure(intn){
        int[] max = { 0,0};
        for(inti =0;i<1000;i++){
            if(n>2*i*i+4*i+1) {
                max[0] = i;
                max[1] = n-2*i*i-4*i-1;
            }
            elsebreak;
        }
        returnmax;
    }
 
}

发表于 2016-08-09 16:15:42 回复(0)
__author__ = 'Yaicky'

def binarySearch(n, rlt):
    left, right = 0, len(rlt)-1
    mid = (left + right) / 2

    while left != right:
        if rlt[mid] == n:
            return mid, rlt[mid]
        elif rlt[mid] > n:
            if rlt[mid-1] <= n:
                return mid-1, rlt[mid-1]
            else:
                right = mid-1
        elif rlt[mid] < n:
            if rlt[mid+1] >= n:
                return mid, rlt[mid]
            else:
                left = mid+1

        mid = (left + right) / 2

rlt = [0, 1]
for i in range(2, 25):
    rlt.append(rlt[i-1]+(4*i-2))

while True:
    try:
        string = raw_input().strip().split(' ')
        num = int(string[0])
        ch = string[1]

        if num == 1:
            print ch
            print 0
        else:
            line, rest = binarySearch(num, rlt)
            rest = num -rest

            for i in range(line,0,-1):
                str = ' '*(line-i) + ch*(2*i-1)
                print str
            for i in range(2, line+1):
                str = ' '*(line-i) + ch*(2*i-1)
                print str
            print rest
            # print rlt
            # print binarySearch(num, rlt)
    except:
        break
右边没有空格真的是。。我就说怎么一直报错

编辑于 2016-07-01 14:17:53 回复(3)
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
	double n, m, r;
	char c;
	cin >> n >> c;
	m = (int)sqrt((n + 1) / 2);
	r = n - (2 * m*m - 1);
	for (int i = 0; i<2 * m - 1; i++)
	{
		if (i<m)
		{
			for (int j = 0; j<i; j++)
				cout << " ";
			for (int k = 0; k<2 * m - 2 * i - 1; k++)
				cout << c;
		}
		else {
			for (int j = 0; j<2 * m - 2 - i; j++)
				cout << " ";
			for (int k = 0; k < 2 * i - 2 * m + 3; k++)
				cout << c;
		}
		cout << endl;
	}
	cout << r;
	return 0;
}

发表于 2016-02-25 16:33:05 回复(0)
大爷的,右侧是不要空格的


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class e1027 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] s = bf.readLine().split(" ");
int n = Integer.valueOf(s[0]);
int r = (int) Math.sqrt((n + 1) / 2);
int t = 2 * r - 1;
int m = n - 2 * r * r + 1;
for (int i = 0; i < t; i++) {
for (int j = 0; j < t; j++) {
if((i<=j&&i+j<=t-1)||(i>=j&&i+j>=t-1)){
System.out.print(s[1]);
}else if(i>j&&i+j<t-1){
System.out.print(" ");
}
}
System.out.println();
}
System.out.println(m);
}
}
编辑于 2016-01-30 13:06:21 回复(2)
这个为啥不通过呢??
#include<stdio.h>
#include<math.h>
int main()
{
    int a[23];
    int b,d,i,j,N;
    char c;
    char H[1000][1000];
    for(i=0;i<1000;i++)
        for(j=0;j<1000;j++)
            H[i][j]='\0';
    scanf("%d %c",&N,&c);
    b=int(sqrt((N+1)/2.0));
    d=N-2*b*b+1;
    for(i=0;i<23;i++)
        a[i]=0;
    for(i=0;i<2*b-1;i++)
        for(j=i;j<2*b-1-i;j++)      
            H[i][j]=c;
    for(i=b;i<2*b-1;i++)
        for(j=2*b-2-i;j<i+1;j++)
            H[i][j]=c;
    for(i=0;i<2*b-1;i++)
    {
        for(j=0;j<2*b-1;j++)
        {
            printf("%c",H[i][j]);
        }
        printf("\n");
    }
    printf("%d\n",d);
    return 0;
}
发表于 2015-07-01 11:12:23 回复(1)
import java.util.Scanner;

/**
 * 打印沙漏
 * 题目描述
 * 本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
 * *****
 *  ***
 *   *
 *  ***
 * *****
 * 所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数
 * 先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
 * 给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
 * 输入描述:
 * 输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。
 * 输出描述:
 * 首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
 * 输入例子:
 * 19 *
 * 输出例子:
 * *****
 *  ***
 *   *
 *  ***
 * *****
 * 2
 *
 * @author shijiacheng
 * @date 2018/2/1
 */
public class B1017PrintHourglass {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        String str = sc.next();

        double temp = Math.pow((N+1)*1.0/2,0.5);
        int n = (int) temp;

        for (int i = n; i > 1; i--) {
            for (int j = 0; j < n-i; j++) {
                System.out.print(" ");
            }
            for(int k = 0; k < 2*i-1; k++){   //每行要打印的符号的个数(相对于前一行多两个)
                System.out.print(str);
            }
            System.out.println();   //换行打印
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < n-i; j++) {
                System.out.print(" ");
            }
            for(int k = 0; k < 2*i-1; k++){   //每行要打印的符号的个数(相对于前一行多两个)
                System.out.print(str);
            }
            System.out.println();   //换行打印
        }
        int sum = N-(2*n*n-1);
        System.out.println(sum);
    }
}
发表于 2018-02-01 22:20:10 回复(1)