23. 图形编辑器
成绩: 10 / 折扣: 0.8
背景
图形编辑器(graphical editor)允许用户改变位图图像,比如大家经常用到的Photoshop。它所采用的改变方法和文本编辑器允许修改文档的方法一样。位图图像由MxN的像素矩阵来表示,并且每个像素点都有给定的颜色。
我们的任务就是来要编写一个程序来模拟一个简单的交互式图形编辑器。
输入
输入由一组编辑命令序列组成,每条序列占一行。每个命令都是由一个大写字母表示的,且放在每行序列首字符的位置上。如果命令需要带参数,那么给出的参数将和命令放在同一行,并用空格相互隔开。 像素点的坐标用两个整数表示,列坐标的范围是从1到M,而行坐标的范围则是从1到N(1<M,N<=250)。坐标原点位于矩阵的左上角。像素点的颜色由大写字母指定。
下面描述了图形编辑器可以接收的命令内容:
I M N | 表示产生一个新的MxN大小的图像,并且图像中所有像素点的初始颜色都为白色(0)。 |
C | 表示通过把所有像素点设置为白色的方法来清除表格。且矩阵的大小保持不变。 |
L X Y C | 表示把坐标为(X,Y)的像素点的颜色涂成颜色(C)。 |
V X Y1 Y2 C | 表示画一条颜色为(C)的垂直线段,线段的列坐标为X,行坐标在Y1到Y2之间,并且包括Y1和Y2两点。 |
H X1 X2 Y C | 表示画一条颜色为(C)的水平线段,线段的行坐标为Y,列坐标在X1到X2之间,并且包括X1和X2两点。 |
K X1 Y1 X2 Y2 C | 表示画一个填充颜色为(C)的矩形,坐标(X1,Y1)是矩形的左上角,而坐标(X2,Y2)则是矩形的右下角。 |
F X Y C | 表示用颜色(C)填充区域R。区域R的定义如下:像素点(X,Y)属于区域R。和像素点(X,Y)颜色一样,并且与区域R内的任何像素点共享一个公共边的其他任何像素点也都属于区域R。 |
S Name | 表示用MSDOS 8.3的格式写文件名,并且文件名后边跟着当前图像的内容。 |
X | 表示终止此次对话操作。 |
输出
在执行每一个S NAME命令时,打印出用NAME(不超过70个字符)命名的文件名(占一行),以及当前图像的内容。图像的每一行用每个像素点的颜色内容来表示。参见输出样例。
输出要忽略掉不用上述字母(即I、C、L、V、H、K、F、S和X)定义的任何命令行,并且继续执行下面的命令。遇到其他错误情况时,程序的运行将无法预测。
来源
http://acm.uva.es/p/v102/10267.html#include<stdio.h>
#include<string.h>
char canvas[252][252],name[71],color;
int M,N;
void build();
void fill(int x,int y,char c);
int main()
{ char order,c,error[100];
int x,y,x1,x2,y1,y2,t,i,j;
do{
scanf("%c",&order);
getchar();
switch(order) /*I、C、L、V、H、K、F、S和X*/
{
case 'I' : { scanf("%d%d",&M,&N);
getchar();
build();
break;
}
case 'C' : { build();
break;
}
case 'L' : { scanf("%d%d",&x,&y);
getchar();
scanf("%c",&color);
getchar();
canvas[y][x]=color;
break;
}
case 'V' : { scanf("%d%d%d",&x,&y1,&y2);
getchar();
scanf("%c",&color);
getchar();
if(y1>y2)
{ t=y1;
y1=y2;
y2=t;
}
for(i=y1;i<=y2;i++)
canvas[i][x]=color;
break;
}
case 'H' : { scanf("%d%d%d",&x1,&x2,&y);
getchar();
scanf("%c",&color);
getchar();
if(x1>x2)
{ t=x1;
x1=x2;
x2=t;
}
for(i=x1;i<=x2;i++)
canvas[y][i]=color;
break;
}
case 'K' : { scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
getchar();
scanf("%c",&color);
getchar();
if(x1>x2)
{ t=x1;
x1=x2;
x2=t;
}
if(y1>y2)
{ t=y1;
y1=y2;
y2=t;
}
for(i=y1;i<=y2;i++)
for(j=x1;j<=x2;j++)
canvas[i][j]=color;
break;
}
case 'F' : { scanf("%d%d",&x,&y);
getchar();
scanf("%c",&color);
getchar();
c=canvas[y][x];
fill(y,x,c);
for(i=1;i<=N;i++)
for(j=1;j<=M;j++)
{ if(canvas[i][j]=='\0')
canvas[i][j]=color;
}
break;
}
case 'S' : { gets(name);
printf("%s\n",name);
for(i=1;i<=N;i++)
printf("%s\n",&canvas[i][1]);
break;
}
default : { if(order!='X')
gets(error);}
}
}while(order!='X');
return 0;
}
void build( )
{ int i,j;
for(i=1;i<=N;i++)
{ for(j=1;j<=M;j++)
canvas[i][j]='0';
canvas[i][j]='\0';
}
return;
}
void fill(int y,int x,char c)
{
if(canvas[y][x]==c||canvas[y][x]=='0')
canvas[y][x]='\0';
else
return;
if(x!=1)
fill(y,x-1,c);
if(x!=M)
fill(y,x+1,c);
if(y!=1)
fill(y-1,x,c);
if(y!=N)
fill(y+1,x,c);
return ;
}