本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递
增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
19 *
***** *** * *** *****
直接把每层的数量求出来放到一个数组里面,遍历这个数组打印就可以了。
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)
#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;
}
#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;
}
}
//坑处在于右侧不需要打印空格。。总是格式不对
#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;
}
}
//这个应该比较简洁了吧
#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;
} 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 语言: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; }
#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;
}
注意一点:右侧不满一行的不需要空格!!!
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();
}
}
格式出错什么鬼? -。-
#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;
}
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;
}
} |
__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
#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;
}
大爷的,右侧是不要空格的
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);
}
}
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;//思路:对每个数加1除以2再开方,取整所得结果就是单个边数,在*2-1就是层数
int main()
{
char s;
int N,n,t,i,j;//n代表层数,t为未使用的个数,最外层数也为n
scanf("%d %c",&N,&s);
n=sqrt((N+1)/2);
t=N-2*n*n+1;
n=n*2-1;
for(i=0;i<n/2;i++)
{
for(j=0;j<i;j++)
printf(" ");
for(j=n-2*i;j>0;j--)
printf("%c",s);
printf("\n");
}
for(i=n/2;i<n;i++)
{
for(j=0;j<n-1-i;j++)
printf(" ");
for(j=0;j<2*i-2*(n/2)+1;j++)
printf("%c",s);
printf("\n");
}
printf("%d\n",t);
return 0;
} 首先可以证明,这个漏斗是一个等差数列。令n表示第n行,表示第
n行所含有的元素个数,表示前
n行元素总数。那么一个:
*** ***** *******
这样的图形,我们直接将3个元素作为第一行(后面指出为什么这样做),则得到,
,联立
可得
本题条件需要用正整数组成的最大的沙漏形状,则需要根据
1中来反推出漏斗的最大高度,这里我们为了区别,令
x为最大高度,其中的x就是我们所需要的。
这里我们通过一个循环(是否小于等于
N)来计算出最大高度x。同时,这里也就回答了之前为什么从有3个元素的行开始:题目要求倒着和正着各一个沙漏,其中他们的第一行是重叠的,且第一行恒为1,所以直接从第二行计算更好。
int x,m,n;//x:一个三角的层数,且3个元素作为第一行;
for (x = 1; x <= N;x++){
if (2 * x*(x + 2) + 1 > N){
x--;//这里得到的x是第一次得到沙漏总个数大于N时,x的层数;而我们要求出总个数小于等于N时的最大层数,那么减去1就是我们需要的。
break;
}
} 如何输出?得到最大行数后,剩下就是输出问题了。
按照一般思想,二维数组双循环+索引关系也是可以解决的,但是逻辑上是有重复的,而且容易乱。
考虑,另一种关系,每一个循环变量不再是索引,而是数量关系,那么这个问题逻辑上就会简化。
for (int i = x; i >= 0;i--){ //打印倒三角,注意行数索引i是从x到0的
for (int j = 0; j < x - i;j++){ //输出空格,每一行有(行数-i)个空格
printf(" "); //最后一行有(行数)个空格
}
for (int j = 0; j < 2 * i + 1;j++){ //输出符号,每一行有2i + 1个符号(等差数列公式)
printf("%c",C);
}
printf("\n");
}
for (int i = 1; i <= x;i++){ //打印正三角,不含第一行,注意行数索引i是从1到x的
for (int j = 0; j < x-i;j++){ //每一行有(x-i)个空格
printf(" ");
}
for (int j = 0; j < 2 * i + 1;j++){ //每一行有 2i + 1个符号
printf("%c", C);
}
printf("\n");
} 完整代码
/*
* app=PAT-Basic lang=c++
* https://pintia.cn/problem-sets/994805260223102976/problems/994805294251491328
*/
#include <cstdio>
using namespace std;
int main()
{
int N;
char C;
scanf("%d %c",&N,&C);
int x,m,n;//x:一个三角的层数,且3个元素作为第一行;
for (x = 1; x <= N;x++){
if (2 * x*(x + 2) + 1 > N){
x--;//这里得到的x是第一次得到沙漏总个数大于N时,x的层数;而我们要求出总个数小于等于N时的最大层数,那么减去1就是我们需要的。
break;
}
}
for (int i = x; i >= 0;i--){ //打印倒三角,注意行数索引i是从x到0的
for (int j = 0; j < x - i;j++){ //输出空格,每一行有(行数-i)个空格
printf(" "); //最后一行有(行数)个空格
}
for (int j = 0; j < 2 * i + 1;j++){ //输出符号,每一行有2i + 1个符号(等差数列公式)
printf("%c",C);
}
printf("\n");
}
for (int i = 1; i <= x;i++){ //打印正三角,不含第一行,注意行数索引i是从1到x的
for (int j = 0; j < x-i;j++){ //每一行有(x-i)个空格
printf(" ");
}
for (int j = 0; j < 2 * i + 1;j++){ //每一行有 2i + 1个符号
printf("%c", C);
}
printf("\n");
}
printf("%d", N - 2 * x*(x + 2) - 1);
return 0;
}