题目:来源http://noi.openjudge.cn/ch0112/09/
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
给定m行n列的图像各像素点灰度值,对其依次进行一系列操作后,求最终图像。
其中,可能的操作及对应字符有如下四种:
A:顺时针旋转90度;
B:逆时针旋转90度;
C:左右翻转;
D:上下翻转。
- 输入
- 第一行包含两个正整数m和n,表示图像的行数和列数,中间用单个空格隔开。1 <= m <= 100, 1 <= n <= 100。
接下来m行,每行n个整数,表示图像中每个像素点的灰度值,相邻两个数之间用单个空格隔开。灰度值范围在0到255之间。
接下来一行,包含由A、B、C、D组成的字符串s,表示需要按顺序执行的操作序列。s的长度在1到100之间。 - 输出
- m‘行,每行包含n‘个整数,为最终图像各像素点的灰度值。其中m‘为最终图像的行数,n‘为最终图像的列数。相邻两个整数之间用单个空格隔开。
- 样例输入
-
2 3 10 0 10 100 100 10 AC
- 解析:
- 题目要求转换最终的结果。分析题目发现,它的变换情况只有两种:旋转、翻转(轴对称)。
- 通过我们自己的想象可以知道:
- 无论图形按照ABCD的命令怎么变换,最终也只会有八种形态:
- 1.不翻转,顺时针旋转0°,即不变
- 2.不翻转,顺时针旋转90°
- 3.不翻转,顺时针旋转180°
- 4.不翻转,顺时针旋转2700°
- 5.按某一个方向翻转后,顺时针旋转0°
6.按某一个方向翻转后,顺时针旋转90°
7.按某一个方向翻转后,顺时针旋转180°
8.按某一个方向翻转后,顺时针旋转270° - (为了方便,我们同一将 “按某一个方向翻转” 改为 “按图形左边缘为对称轴进行轴对称”)
- 于是我们可以画出图形经过翻转后的八种形态(对于我这个懒人,拿一张纸直接变换,是懒得用脑子想象的一种好方法)。
1 | 2 | 3 | 4 | |||||||||||
1 | 2 | 3 | 7 | 4 | 1 | 9 | 8 | 7 | 3 | 6 | 9 | |||
4 | 5 | 6 | 8 | 5 | 2 | 6 | 5 | 4 | 2 | 5 | 8 | |||
7 | 8 | 9 | 9 | 6 | 3 | 3 | 2 | 1 | 1 | 4 | 7 | |||
5 | 6 | 7 | 8 | |||||||||||
3 | 2 | 1 | 9 | 6 | 3 | 7 | 8 | 9 | 1 | 4 | 7 | |||
6 | 5 | 4 | 8 | 5 | 2 | 4 | 5 | 6 | 2 | 5 | 8 | |||
9 | 8 | 7 | 7 | 4 | 1 | 1 | 2 | 3 | 3 | 6 | 9 |
- 最朴素的算法,就是按照命令的形式,一次一次地翻转图形,但是这很耗时间,基本上就别想Accept了。
- 我们在此基础上做了点改进:
- 按照命令的形式,一次一次地翻转“图形的形态”
- ——什么意思?我们可以把图形每种样子做一个编码,就像警察发通缉令,有时候嫌疑人的照片一张不够:戴牛仔帽的,穿夹克的,叼雪茄的……我们也是如此(如上图所示)。
- 我们在一个函数中完成对命令的解析,传回图形最后的形态(给它一顿最后的晚餐~~)。
- 之后也有一种优化的方法:
- 原来我们想着就直接把图形真正做一个变换,但是如果图形太大,这也很耗时间;
- 所以我们不妨从输出下手,改变输出的顺序,来达到变换图形的效果。
- 代码:(为人类造福)
1 #include <stdio.h> 2 #include <string.h> 3 struct command{ 4 char str[101]; 5 int length; 6 }; 7 int ExplainCommand(struct command s); 8 void Print(int *pho,int way,int height,int width); 9 int main() 10 { 11 int m,n,i,j; 12 int pho[10000]; 13 struct command s; 14 15 16 scanf("%d%d",&m,&n); 17 for(i=0;i<m;i++) 18 { 19 for(j=0;j<n;j++) 20 { 21 scanf("%d",&pho[i*n+j]); 22 } 23 } 24 getchar(); 25 gets(s.str); 26 s.length=strlen(s.str); 27 28 Print(pho,ExplainCommand(s),m,n); 29 30 return 0; 31 } 32 int ExplainCommand(struct command s)//对命令行做解析,分析出最终的形态 33 { 34 int ans=1;//假定目前最终形态为不变 35 int i; 36 for(i=0;i<s.length;i++) 37 { 38 if(s.str[i]==‘A‘) 39 { 40 switch(ans) 41 { 42 case 1: ans=2 ;break; 43 case 2: ans=3 ;break; 44 case 3: ans=4 ;break; 45 case 4: ans=1 ;break; 46 case 5: ans=6 ;break; 47 case 6: ans=7 ;break; 48 case 7: ans=8 ;break; 49 case 8: ans=5 ;break; 50 } 51 } 52 53 else if(s.str[i]==‘B‘) 54 { 55 switch(ans) 56 { 57 case 1: ans=4 ;break; 58 case 2: ans=1 ;break; 59 case 3: ans=2 ;break; 60 case 4: ans=3 ;break; 61 case 5: ans=8 ;break; 62 case 6: ans=5 ;break; 63 case 7: ans=6 ;break; 64 case 8: ans=7 ;break; 65 } 66 } 67 else if(s.str[i]==‘C‘) 68 { 69 switch(ans) 70 { 71 case 1: ans=5 ;break; 72 case 2: ans=8 ;break; 73 case 3: ans=7 ;break; 74 case 4: ans=6 ;break; 75 case 5: ans=1 ;break; 76 case 6: ans=4 ;break; 77 case 7: ans=3 ;break; 78 case 8: ans=2 ;break; 79 } 80 } 81 else if(s.str[i]==‘D‘) 82 { 83 switch(ans) 84 { 85 case 1: ans=7 ;break; 86 case 2: ans=6 ;break; 87 case 3: ans=5 ;break; 88 case 4: ans=8 ;break; 89 case 5: ans=3 ;break; 90 case 6: ans=2 ;break; 91 case 7: ans=1 ;break; 92 case 8: ans=4 ;break; 93 } 94 } 95 } 96 return ans; 97 } 98 void Print(int *pho,int way,int height,int width) 99 { 100 /*图形经过各种旋转变换后,最后的形态只有8种 101 *前四种: 102 *1=未翻转,顺时针旋转 0 103 *2=未翻转,顺时针旋转 90 104 *3=未翻转,顺时针旋转 180 105 *4=未翻转,顺时针旋转 270 106 *后四种: 107 *5=以图形左边为对称轴对称,顺时针旋转 0 108 *6=以图形左边为对称轴对称,顺时针旋转 90 109 *7=以图形左边为对称轴对称,顺时针旋转 180 110 *8=以图形左边为对称轴对称,顺时针旋转 270 111 */ 112 int i,j,temp; 113 114 115 if(way==1) 116 { 117 for(i=0;i<height;i++) 118 { 119 for(j=0;j<width;j++) 120 { 121 temp=*(pho+i*width+j); 122 printf("%d ",temp); 123 } 124 printf("\n"); 125 } 126 } 127 128 129 else if(way==2) 130 { 131 for(j=0;j<width;j++) 132 { 133 for(i=height-1;i>=0;i--) 134 { 135 temp=*(pho+i*width+j); 136 printf("%d ",temp); 137 } 138 printf("\n"); 139 } 140 } 141 142 143 else if(way==3) 144 { 145 for(i=height-1;i>=0;i--) 146 { 147 for(j=width-1;j>=0;j--) 148 { 149 temp=*(pho+i*width+j); 150 printf("%d ",temp); 151 } 152 printf("\n"); 153 } 154 } 155 156 157 else if(way==4) 158 { 159 for(j=width-1;j>=0;j--) 160 { 161 for(i=0;i<height;i++) 162 { 163 temp=*(pho+i*width+j); 164 printf("%d ",temp); 165 } 166 printf("\n"); 167 } 168 169 } 170 171 172 else if(way==5) 173 { 174 for(i=0;i<height;i++) 175 { 176 for(j=width-1;j>=0;j--) 177 { 178 temp=*(pho+i*width+j); 179 printf("%d ",temp); 180 } 181 printf("\n"); 182 } 183 } 184 185 186 else if(way==6) 187 { 188 for(j=width-1;j>=0;j--) 189 { 190 for(i=height-1;i>=0;i--) 191 { 192 temp=*(pho+i*width+j); 193 printf("%d ",temp); 194 } 195 printf("\n"); 196 } 197 } 198 199 200 else if(way==7) 201 { 202 for(i=height-1;i>=0;i--) 203 { 204 for(j=0;j<width;j++) 205 { 206 temp=*(pho+i*width+j); 207 printf("%d ",temp); 208 } 209 printf("\n"); 210 } 211 } 212 213 214 else if(way==8) 215 { 216 for(j=0;j<width;j++) 217 { 218 for(i=0;i<height;i++) 219 { 220 temp=*(pho+i*width+j); 221 printf("%d ",temp); 222 } 223 printf("\n"); 224 } 225 } 226 227 return ; 228 }
不点开就不用花钱
请不要问我为什么不用二维数组——因为在传参数的时候真心不好用……
即使是用指针也如此(因为我不会呀~~)
时间: 2024-10-14 04:31:39