NOI 练手题 图像旋转翻转变换

题目:来源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

NOI 练手题 图像旋转翻转变换的相关文章

KMP算法的定义及KMP练手题 HDU 1711 Number Sequence (我的模板代码)

题意:就是要你来找出b数组在a数组中最先匹配的位置,如果没有则输出-1 思路:直接KMP算法(算法具体思想这位牛写的不错http://blog.csdn.net/v_july_v/article/details/7041827) AC代码: #include<cstdio> #include<cstring> #include<stdlib.h> #include<iostream> using namespace std; #define maxn 100

练手题,没事就来AC吧 poj 4044 Score Sequence

此题为12年金华邀请赛A题 克隆了下比赛,A题最简单,也是最挑战人数据处理能力的一题,可惜自己数据处理能力太弱 久久不能写出代码---- 总结下就是题做少了,平时应多做题,少灌水,应放下看电影的时间,玩各种软件的时间 先做好一项再说才是正道,看到一句话说得好 "   人有两条路要走,一条是必须走的,一条是想走的,你必须把必须走的路走漂亮,才可以走想走的路..." 不扯了,贴代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

百练-16年9月推免-C题-图像旋转

C:图像旋转 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数.1 <= n <= 100,1 <= m <= 100.接下来n行,每行m个整数,表示图像的每个像素点灰度.相邻两个整数之间用单个空格隔开,每个元素均在0~255之间. 输出 m行,每行n个整数,为顺时针旋转90度后的图像.相邻两个整数之间用单个空格隔开. 样

KMP——模板 练手题

1. 洛谷  P3375 [模板]KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了. 输入输出格式 输入格式: 第一行为一个字符串,即为s1(仅包含大写字母) 第二行为一个字符串,即为s2(仅包含大写字母) 输出格式: 若干行,每行包含一个整数,表示s2在s1中出现的位置 接下来1行,包括length

【背包问题】【出来混总是要还的...】总结+入门练手题

花了一晚上加一早上研究背包,唉一大把年纪了才狠下心弄dp也确实说不过去的...... 背包入门当然还是看背包九讲(链接很多,没找到原作的,就随便贴一个链接了...),我再扯也是班门弄斧,只是贴一些摘要以及写代码时候的总结吧. 01背包:有N件物品和一个容量为V的背包.第i件物品的体积是v[i],价值是val[i],每种只有一件.求解将哪些物品装入背包可使价值总和max_val最大. max_val[i][j] -->  dp[i][j] : 从前i个物品中选择重量不超过j的物品时的最大价值: m

day-1.python初学者练手题

1.编写一个名为right_justify的函数,函数接受一个名为``s``的字符串作为形参, 并在打印足够多的前导空格(leading space)之后打印这个字符串,使得字符串的最后一个字母位于显示屏的第70列. def right_justify(s): length = len(s) lspace = 70 - length so = ' ' * lspace + s print(so) right_justify('dean') 2.函数对象是一个可以赋值给变量的值,也可以作为实参传递

Pandas数据分析练手题(十题)

数据集下载地址:https://github.com/Rango-2017/Pandas_exercises ---------------------------------------------------------------------------------------------------------------------- 1 - 开始了解你的数据 探索Chipotle快餐数据 -- 将数据集存入一个名为chipo的数据框内-- 查看前10行内容-- 数据集中有多少个列(c

java 水题练手汇总

最近学java,会陆续找点水题练手. 题目链接 1 import java.util.*; 2 import java.awt.*; 3 import java.math.*; 4 5 public class Main { 6 7 public static void main(String args[]) { 8 Scanner cin=new Scanner(System.in); 9 int n, i; 10 int f[] = new int[35]; 11 f[0] = 0; 12

MemSQL Start[c]UP 2.0 - Round 1(无聊练手B题)

http://codeforces.com/contest/452/problem/B B. 4-point polyline time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a rectangular grid of lattice points from (0, 0) to (n, m) inc