PAT乙级1027

65 阅读1分钟

image.png 画图找规律的题目,找到行数,空格与字符的规律。

以中间的行为基准,向两边散发行,每一行都是奇数个字符。以中间行为第0行,因为两边是对称的,值计算一边再乘以2就行。散发开来每行是3,5,7~~~ 。设有x行,那么可以得出第i行是(2i+1)[3,5,7,9,~,2i+1]。根据求和公式,仅上中间行0行上面的字符数是: (3+2i+1)i/2=i(i+2)(3 + 2i + 1) * i / 2 = i * (i + 2)。而总的字符数为2i(i+2)+12 * i * (i + 2) + 1。所以当所需字符数大于n(可使用的字符数)时,说明最多行了。

而输入规则,先输入0行上面的,再输入0行本身,最后时0行下面的,而每一行先要输入一定的空格,空格数就是单侧行数 - 输入到第几行。0行前就输入单侧行数个数的空格。注意两侧时对称的哦。

//foreverking
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
//谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等
int main(){
    int n,cnt = 0;
    char ch;
    cin >> n >> ch;
    for(int i = 0; i < n; i++){
        if((2 * i * (i + 2) + 1) > n){
            cnt = i - 1;//这时候层数应该是i-1
            break;//跳出循环
        }
    }
    // cout << cnt;
    for(int i = cnt ; i > 0; i--){//上面的行
        for(int j = cnt - i; j > 0; j--) cout << ' ';//输入空格
        for(int k = 0; k < i * 2 + 1; k++) cout << ch;
        cout << endl;
    }
    //输入中间的一行,只有一个字符
    for(int i = 0 ; i < cnt; i++) cout << ' ';
    cout << ch << endl;
    //输入下main的行
    for(int i = 1 ; i <= cnt; i++){//下面的行
        for(int j = cnt - i; j > 0; j--) cout << ' ';//输入空格
        for(int k = 0; k < i * 2 + 1; k++) cout << ch;
        cout << endl;
    }
    cout << n - (2 * cnt * (cnt + 2) + 1);
    return 0;
}

题目链接