图案变换问题(湖南省首届“湘邮科技杯”大学生程序设计大赛试题)

图案变换问题

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte

描述

给出一个正方形图案和它的变换图案,称为图案变换对。编写程序,求图案变换对之间的最小变换。图案是由黑白两种小方块构成的。可能的变换包括:

  (1)  旋转 90 度:图案顺时针旋转 90 度,记做 rot90
  (2)  旋转 180 度:图案顺时针旋转 180 度,记做 rot180
  (3)  旋转 270 度:图案顺时针旋转 270 度,记做 rot270
  (4)  竖直映像:图案以其上方的一条平行线为轴翻转,记做 vr
  (5)  联合变换:图案首先做一次竖直映像变换,然后做一次旋转变换,记做 vr-rot90 或 vr-rot180 或vr-rot270
  (6)  保持:图案和变换后的图案完全一样,记做 idt
  (7)  错误:无法应用上述变换将初始图案变换成它的变换图案,记做 imp

 

输入

输入文件中包含多组图案变换对。每一对图案数据的起始行都是一个整数,表示正方形图案的边长 a(以一个小方块为单位,1<=a<=100) ,后续的 a 行,每一行包含了原图案的一行和变换图案的对应行,两者之间用一个空格分开。黑色小方块用 b 表示,白色小方块用 o 表示。

输出

输出文件的每一行对应输入文件的每一个图案变换对。其中每行开始的整数表示对应图案对在输入文件中出现的序号,紧跟一个空格,然后就是该图案对的最小变换,采用上述记号表示。

 
备注:为了比较不同变换的大小,定义:旋转变换的代价小于映像变换,小角度旋转变换的代价小于大角度旋转变换,保持变换的代价最小。注意:对本题而言,只有上面列出的变换是合法的,如果某个图案对可以由多个变换得到,则应选择代价最小的变换。

 

样例输入

5
booob oooob
obooo ooobo
ooobo obooo
oobob ooboo
oooob bboob
6
oooobb boooob
oooboo bobooo
bboobo oboobo
oobooo ooobob
oooboo oobooo
ooboob oobooo
2
bo bo
ob ob
4
oobo ooob
bboo oooo
oooo bboo
ooob oobo
5
boooo obooo
obooo ooboo
obooo ooboo
ooobo oooob
oooob boooo
4
oboo oobo
obob booo
oooo oobb
oobo oooo
2
oo bb
bb oo

 

样例输出

1 rot90
2 rot270
3 idt
4 vr
5 imp
6 vr-rot270
7 rot180
 
题解:只要根据旋转的特点来找到坐标的规律即可。
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

int n;
char str[110][110],op[110][110];

int idt() // 完全一样
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[i][j])
                return 0;
    return 1;
}

int rot90() //顺时针旋转90度
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[j][n-i-1])
                return 0;
    return 1;
}
int rot180() //顺时针旋转180度
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[n-i-1][n-j-1])
                return 0;
    return 1;
}
int rot270() //顺时针旋转270度
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[n-j-1][i])
                return 0;
    return 1;
}
int vr() //竖直映像
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[n-i-1][j])
                return 0;
    return 1;
}

int vr_rot90()
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[j][i])
                return 0;
    return 1;
}

int vr_rot180()
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[i][n-j-1])
                return 0;
    return 1;
}
int vr_rot270()
{
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            if(str[i][j]!=op[n-j-1][n-i-1])
                return 0;
    return 1;
}
int main()
{
    int ans=1;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%s",str[i]);
            scanf("%s",op[i]);
        }
        printf("%d ",ans++);
        if(idt())
        {
            printf("idt\n");
            continue;
        }
        if(rot90())
        {
            printf("rot90\n");
            continue;
        }
        if(rot180())
        {
            printf("rot180\n");
            continue;
        }
        if(rot270())
        {
            printf("rot270\n");
            continue;
        }
        if(vr())
        {
            printf("vr\n");
            continue;
        }

        if(vr_rot90())
        {
            printf("vr-rot90\n");
            continue;
        }
        if(vr_rot180())
        {
            printf("vr-rot180\n");
            continue;
        }
        if(vr_rot270())
        {
            printf("vr-rot270\n");
            continue;
        }
        printf("imp\n");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/lavender913/p/3332070.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值