• P5730 【深基5.例10】显示屏


    https://www.luogu.com.cn/problem/P5730

    P5730 【深基5.例10】显示屏 题解

    题目的意思很明确,要我们通过输入的数字来构建一个显示屏,使得上面显示这些数字。

    许多题解里建立了一个三维char数组来存储每一个数字,然后进行输出,其中打表浪费了大量的时间。我想,既然样例输出里就有现成的(0 o 9)每一个数字的形状,为什么不直接拿过来用呢?

    首先我建立了一个数组base_1来存储样例输出,注意这里行和列的大小一定要准确,因为字符串是以结尾的,独占一个空间:

    char base_1[5][40]={
    	"XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX",
    	"X.X...X...X...X.X.X.X...X.....X.X.X.X.X",
    	"X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX",
    	"X.X...X.X.....X...X...X.X.X...X.X.X...X",
    	"XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX",
    //   0 2 4 6 8 
    };
    

    这里的注释0 2 4 6 8是什么意思,之后会提到。

    我们将答案存储在一张画布(即“显示屏”)内。now是什么意思,一会儿也会说。

    char pict[6][9999];//画布,即题目中的"显示屏"。 
    int now=0;//表示这个数字应该在画布的第几个位置写入 
    

    这里我的想法是,扫描输入的数字串,然后依次转化成真实数字。接下来的工作是从base_1中“抠取”需要的数字。根据上面的注释,我们会发现,数字(i)base_1中对应的范围是(只写出横向坐标,纵向坐标就是(0 o 4)):([4i,4i+2])。依据这个性质,我们就可以“抠取”需要的数字。

    那么怎么把抠出来的数字写入到画布里呢?这里now就派上用场了。now存储的是下一个数字要在横向坐标的什么位置输入画布。一开始,now=0,然后插入一个数字(比如说(0))之后,now就应该移到4的位置。再在这里插入一个数字1。每次插入一个数字,now就要后移4格。它的作用相当于电脑光标。至于补全一列'.'的时候,我们直接从now-1的位置插入就行。

    处理相对位置有点麻烦,详见注释。注意数组的第一维是纵向坐标,第二维才是横向。并且都是从(0)开始索引计数的:

    void work(string s){
    	for(int p=0;p<s.length();p++){
    		int num=s[p]-'0';//转化成真实数字 
    		int xst=num*4;//这个数字对应的base_1里的位置起始点 
    		for(int i=0;i<=4;i++){//遍历这个数字对应的base_1里的点 
    			for(int j=xst;j<=xst+2;j++){
    				pict[i][j-xst+now]=base_1[i][j];//j-xst将[xst,xst+2]映射为[0,2],再加上now表示从now位置写入画布 
    			}
    		}
    		for(int i=0;i<=4;i++)
    			pict[i][now-1]='.';//补全一列空点 
    		now+=4;//下一个写入的位置 
    	}
    }
    

    输出就比较简单了:

    void print(){//输出 
    	for(int i=0;i<=4;i++){
    		for(int j=0;j<=len*4;j++){//len*4表示预期画布宽度(其实只要这个数字够大就行,C++貌似会自动换行) 
    			cout<<pict[i][j];//即使输入的长度与原数字串长度不相等,它竟然也能正常工作! 
    		}
    		cout<<endl;
    	}
    }
    

    总体AC代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char base_1[5][40]={
    	"XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX",
    	"X.X...X...X...X.X.X.X...X.....X.X.X.X.X",
    	"X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX",
    	"X.X...X.X.....X...X...X.X.X...X.X.X...X",
    	"XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX",
    //   0 2 4 6
    };
    char pict[6][9999];//画布,即题目中的"显示屏"。 
    int now=0;//表示这个数字应该在画布的第几个位置写入 
    int len;//字符串长度
    void work(string s){
    	for(int p=0;p<s.length();p++){
    		int num=s[p]-'0';//转化成真实数字 
    		int xst=num*4;//这个数字对应的base_1里的位置起始点 
    		for(int i=0;i<=4;i++){//遍历这个数字对应的base_1里的点 
    			for(int j=xst;j<=xst+2;j++){
    				pict[i][j-xst+now]=base_1[i][j];//j-xst将[xst,xst+2]映射为[0,2],再加上now表示从now位置写入画布 
    			}
    		}
    		for(int i=0;i<=4;i++)
    			pict[i][now-1]='.';//补全一列空点 
    		now+=4;//下一个写入的位置 
    	}
    }
    void print(){//输出 
    	for(int i=0;i<=4;i++){
    		for(int j=0;j<=len*4;j++){//len*4表示预期画布宽度(其实只要这个数字够大就行,C++貌似会自动换行) 
    			cout<<pict[i][j];//即使输入的长度与原数字串长度不相等,它竟然也能正常工作! 
    		}
    		cout<<endl;
    	}
    }
    int main(){
    	cin>>len;
    	string str;
    	cin>>str;
    	work(str);
    	print();
    	return 0;
    }
    
  • 相关阅读:
    C#读取数据库字节流生成图片
    twitter通过oAuth验证获取json数据
    C#读写txt文件
    asp.net分页方法
    sql分页代码
    acm寒假特辑 1月19日 CodeForces
    acm寒假特辑 1月25日 CodeForces
    snow miku 日记
    错排问题(个人总结/复习用)
    acm寒假特辑 2月2日 HDU
  • 原文地址:https://www.cnblogs.com/jiangyuechen/p/13292327.html
Copyright © 2020-2023  润新知