本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
*****
***
*
***
*****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递
增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入在一行给出1个正整数N(<=1000)和一个符号,中间以空格分隔。
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
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; }
#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; } }//这个应该比较简洁了吧
直接把每层的数量求出来放到一个数组里面,遍历这个数组打印就可以了。
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 <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; }