王道论坛计算机考研机试指南 四 排版题

例2.7 输出梯形 (九度教程第14题)
时间限制:1秒 **内存限制:32兆 ** 特殊判题:否

题目描述:
输入一个高度h,输出一个高为h,上底边为h的梯形。

输入:
一个整数h(1<=h<=1000)。

输出:
h所对应的梯形。

样例输入:
4

样例输出:

      **** 
    ****** 
  ********
**********

提示:
梯形每行都是右对齐的,sample中是界面显示问题

来源:
2001年清华大学计算机研究生机试真题(第II套)

#include <stdio.h>
int main () {
int h;
while (scanf ("%d",&h) != EOF) {
    int maxLine = h + (h - 1) * 2; //计算最后一行包含的星号个数
    for (int i = 1;i <= h;i ++) { //依次输出每行信息
        for (int j = 1;j <= maxLine;j ++) { //依次输出每行当中的空格或星号         
            if (j < maxLine - h - (i - 1) * 2 + 1)
            printf(" ");
            //输出空格           
            else
            //输出星号           
            printf("*");
        }
    printf("\n"); //输出换行
    }    
    }
    return 0;
}
例2.8 叠筐 (九度教程第15题)
时间限制:1秒 **内存限制:32兆 ** 特殊判题:否

题目描述:
把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。

输入:
输入是一个个的三元组,分别是,外筐尺寸n(n为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后二者都为ASCII可见字符;

输出:
输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。

样例输入:
11 B A
5 @ W

样例输出:

 AAAAAAAAA
ABBBBBBBBBA
ABAAAAAAABA
ABABBBBBABA
ABABAAABABA
ABABABABABA
ABABAAABABA
ABABBBBBABA
ABAAAAAAABA
ABBBBBBBBBA 
 AAAAAAAAA 

 @@@
@WWW@
@W@W@
@WWW@ 
 @@@
#include <stdio.h>
int main () {
    int outPutBuf[82][82]; //用于预排版的输出缓存
    char a , b; //输入的两个字符
    int n; //叠框大小
    bool firstCase = true; //是否为第一组数据标志,初始值为true
        while (scanf ("%d %c %c",&n,&a,&b) == 3) {
        if (firstCase == true) { //若是第一组数据
            firstCase = false; //将第一组数据标志标记成false
            }
        else printf("\n"); //否则输出换行
        for (int i = 1,j = 1;i <= n;i += 2,j ++) { //从里至外输出每个圈
            int x = n / 2 + 1 , y = x;
            x -= j - 1;y -= j - 1; //计算每个圈右上角点的坐标
            char c = j % 2 == 1 ? a : b; //计算当前圈需要使用哪个字符
            for (int k = 1;k <= i;k ++) { //对当前圈进行赋值
                outPutBuf[x + k - 1][y] = c; //左边赋值
                outPutBuf[x][y + k - 1] = c; //上边赋值
                outPutBuf[x + i - 1][y + k - 1] = c; //右边赋值
                outPutBuf[x + k - 1][y + i - 1] = c; //下边赋值
            }
        }
        if (n != 1) { //注意当n为1时不需此步骤
            outPutBuf[1][1] = ' ';
            outPutBuf[n][1] = ' ';
            outPutBuf[1][n] = ' ';
            outPutBuf[n][n] = ' '; //将四角置为空格
        }
        for (int i = 1;i <= n;i ++) {
            for (int j = 1;j <= n;j ++) {
                printf("%c",outPutBuf[i][j]);
            }
            printf("\n");
        } //输出已经经过排版的在输出缓存中的数据
    }
    return 0;
}
如该代码所示,我们不再在输出时使用我们得到的规律,而是用另一种更容
易的方法完成排版。我们利用一个缓存数组来表示将要输出的字符阵列,我们对
该字符阵列的坐标作如下规定,规定阵列左上角字符坐标为(1,1),阵列右下
角字符坐标为(n,n),其它坐标可由此推得。程序按照由最内圈至最外圈的的
顺序来完成图形的排列。在完成每圈排列时,我们都需要注意两个要点:首先需
要确定该圈左上角的坐标。我们将以这个坐标为参照点来完成该圈的其它字符位
置的确定(当然也可以选用其它点)。观察图形得知,最中间圈的左上角字符坐
标为(n / 2 + 1,n / 2 + 1),次中间圈的左上角字符坐标为(n / 2 + 1- 1,n / 2 + 1 - 1),,
依次类推即可得到图形中每一个圈的参照点。其次,我们需要计算该圈每边边长
长度。这也较容易得出,中心圈长度为 1,次中心圈长度为 3,依次类推,外圈
总比内圈长度增加 2。注意了这两点以后,我们按照以下顺序完成每圈的排版,
首先明确该圈使用哪一个字符来填充,我们使用判断循环次数指示变量 j 的奇偶
性来判断当前需要使用的字符,即奇数次循环时(j 为奇数)时使用第一个字符,
偶数次循环时使用第二个字符。然后,我们确定该圈左上角字符的坐标,我们使
用中心坐标(n / 2 + 1,n / 2 + 1)减去当前循环次数指示变量 j 来确定该圈左上
角坐标,即(n / 2 + 1- j,n / 2 + 1 - j)。接着,我们计算该圈边长长度,我们利用
初始值为 1 的循环指示变量 i 来表示边长长度,并在每次循环结束后加 2,代表边长由 
1 开始,每外移一个圈边长长度即加上 2。利用变量 i 所存的值我们即可
对当前圈的四条边进行赋值,对应的坐标已在代码中给出,这里不再列举。在完
成所有圈的编排后,我们只需按照题目的需要去除四个角的字符,最后将整个输
出缓存中的字符阵列输出即可。
另外,此代码还有两个注意点值得我们指出。
1.输出格式。题面要求我们在输出的每个叠筐间输出一个空行,即除了最后
一个叠筐后没有多余的空行,其它叠筐输出完成后都需要额外的输出一个空行。
为了完成这个要求,我们将要求形式改变为除了在第一个输出的叠筐前不输出一
个空行外,在其它每一个输出的叠筐前都需要输出一个额外的空行。为完成这一
目的,我们在程序开头设立了 firstCase 变量来表示正在处理数据的是否为第一组
数据,毫无疑问它的初始值为 true。在程序读取每组数据后,我们都测试 firstCase
的值,若其为 true 则表示当前处理的数据为第一组数据,我们不输出空行,并在
此时将 firstCase 变量改变为 false。以后,每当程序读入数据,测试 firstCase 变
量时,该变量均为 false,于是我们完成题目的要求,在输出的叠筐前额外的输
出一个空行,来达到题面对于输出格式的要求。
2.边界数据处理。按上文所说,我们在输出缓存中完成字符阵列排版后,需
要将该阵列四个角的字符修改为空格,但是这一修改不是一定需要的。当输入的
n 为 1 时,该修改会变得多余,它会使输出仅变为一个空格,这与题面要求不符。
因此,在进行该修改之前,我们需要对 n 的数值作出判断,若其不为 1 则进行修
改,否则跳过修改部分。由此不难看出,机试考题要求我们在作答时,不仅能够
大致的把握算法,同时还要细致的考虑边界数据会给我们的程序造成什么样的影
响。只有充分考虑了所有情况,并保证在所有题面明确将会出现的条件下,程序
依旧能够正常工作,这样我们才能使自己的程序真正的万无一失、滴水不漏。
本例介绍了另一种解决排版题的思路,当输出图形所具有的规律不能或者很难直
接应用到输出上时,我们就要考虑采用该例所采用的方法,先用一个二维数组来
保存将要输出的字符阵列,并在该数组上首先完成排版。因为没有了输出时从上
至下、从左至右的顺序限制,我们能更加随意的按照自己的需要或者图形的规律
来依次输出图形,从而完成题目要求。
题目1161 Repeater (九度教程第16题)
时间限制:1秒 **内存限制:32兆 ** 特殊判题:否

来源:
2011年北京大学计算机研究生机试真题

#include<stdio.h>  
#include<stdlib.h>  
#include<math.h>  
int n,q;  
char a[10][10],s[3005][3005];  
void input()  
{  
    int i,j;  
    getchar();  
    for(i=0;i<n;i++)  
    {  
        for(j=0;j<n;j++)  
            scanf("%c",&a[i][j]);  
        getchar();  
    }  
    scanf("%d",&q);  
}  
void print(int x,int y,int p)  
{  
    int i,j;  
    int h,k;  
    if(p==1)  
    {  
        for(i=0;i<n;i++)  
            for(j=0;j<n;j++)  
                s[x+i][y+j]=a[i][j];  
    }  
    else  
    {  
        for(i=0;i<n;i++)  
        {  
            for(j=0;j<n;j++)  
            {  
                if(a[i][j]!=' ')  
                {  
                    print(x+i*pow(n*1.0,(p-1)*1.0),y+j*pow(n*1.0,(p-1)*1.0),p-1);  
                }  
                else  
                {  
                    for(h=x+i*pow(n*1.0,(p-1)*1.0);h<x+(i+1)*pow(n*1.0,(p-1)*1.0);h++)  
                        for(k=y+j*pow(n*1.0,(p-1)*1.0);k<y+(j+1)*pow(n*1.0,(p-1)*1.0);k++)  
                            s[h][k]=' ';  
                }  
            }  
        }  
    }  
}  
int main()  
{  
    int i,j;  
    while(scanf("%d",&n)!=EOF&&n)  
    {  
        input();  
        print(0,0,q);  
        for(i=0;i<pow(n*1.0,q*1.0);i++)  
        {  
            for(j=0;j<pow(n*1.0,q*1.0);j++)  
                printf("%c",s[i][j]);  
            printf("\n");  
        }  
    }  
    return 0;  
}  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容