道可道,非常道

无名者,圣人也
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[原创]USACO:Transformations问题分析

Posted on 2008-03-22 15:13  一岩一道  阅读(1008)  评论(0编辑  收藏  举报

问题:方块转换(译 by  TinyTony)
一块N x N1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案。写一个程序来找出将原始
图案按照以下列转换方法转换成新图案的最小方式:
#1:转90度:图案按顺时针转90度。
#2:转180度:图案按顺时针转180度。
#3:转270度:图案按顺时针转270度。
#4:反射:图案在水平方向翻转(形成原图案的镜像)。
#5:组合:图案在水平方向翻转,然后按照#1-#3之一转换。
#6:不改变:原图案不改变。
#7:无效转换:无法用以上方法得到新图案。
如果有多种可用的转换方法,请选择序号最小的那个。

Promgram Name:transform
Sample Input(file transfrom.in)
3
@-@
---
@@-
@-@
@--
--@
输出要求:
单独的一行包括1到7之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的
转换方法。
Sample Output(file transform.out)
1

问题分析:
对于N阶方阵a,很容易得到其与其顺时针90度旋转所方阵b的关系:bij=a(N+1-j,i),其中i,j>0, i,j<=N
180则为bij在旋转90度所得,则cij=b(N+1-j,j)=a(N+1-j,N+1-i)
270则为:dij=a(j,N+1-i)
对于N阶方阵a,其镜像方阵bij=a(i,N+1-j)
只要遍历数组并判断对项是否相等便可以获得解。
代码如下:

/*
ID: jallery1
LANG: C++
TASK: transform
*/


#include
<iostream>
#include
<fstream>
#include
<string>

using namespace std;

int Transform(char a[][10],char b[][10],int n,int flag);
void Mirror(char a[][10],char c[][10],int n);
int NoChange(char[][10],char[][10],int);
int main()
{
    ifstream fin (
"transform.in");
    ofstream fout (
"transform.out");
    
char a[10][10];
    
char b[10][10];
    
char c[10][10];//存储a的镜面数组
    int n;
    fin
>>n;
    
//读入a,b
    for(int i=0;i<n;i++)
    
{
        
for(int j=0;j<n;j++)
            fin
>>a[i][j];
    }

    
for(int i=0;i<n;i++)
    
{
        
for(int j=0;j<n;j++)
        
{
            fin
>>b[i][j];
        }

    }

    
int result=0;
    
//先判断是否为90,180,270以及镜面
    for(int i=1;i<5;i++)
    
{
        result
=Transform(a,b,n,i); //i代表变换的类型,1为90旋转,2为180旋转
        if(result==i) //如果result和返回的值相等,说明b是i类型变换
        {
            fout
<<result<<endl;
            
return 0;
        }

    }

    Mirror(a,c,n);
//获得a的镜像c
    for(int i=1;i<5;i++)//组合类型判断,c和b
    {
        result
=Transform(c,b,n,i);
        
if(result==i)
        
{
            result
=5;
            fout
<<result<<endl;
            
return 0;
        }

    }

    result
=NoChange(a,b,n);//无变换判断
    if(result<7){
        fout
<<result<<endl;
        
return 0;
    }

    result
=7;
    fout
<<result<<endl;
    
return 0;
}


int Transform(char a[][10],char b[][10],int n,int flag)
{
    
bool equal=false;
    
for(int i=0;i<n;i++)
    
{
        
for(int j=0;j<n;j++)
        
{
            
switch(flag)
            
{
            
case 1//90变换
                equal=(b[i][j]==a[n-1-j][i]);
                
break;
            
case 2//180变换
                equal=(b[i][j]==a[n-i-1][n-j-1]);
                
break;
            
case 3:    //270变换
                equal=(b[i][j]==a[j][n-i-1]);
                
break;
            
case 4://Mirror变换
                equal=(b[i][j]==a[i][n-j-1]);
                
break;
            }

            
if(!equal) break;
        }

        
if(!equal) break;
    }

    
if(!equal) flag=7;
    
return flag;
}

void Mirror(char a[][10],char c[][10],int n) //将a的镜面存储为c
{
    
for(int i=0;i<n;i++)
    
{
        
for(int j=0;j<n;j++)
        
{
            c[i][j]
=a[i][n-j-1];
        }

    }

}

int NoChange(char a[][10],char b[][10],int n)//无变换
{
    
int flag=6;
    
for(int i=0;i<n;i++)
    
{
        
for(int j=0;j<n;j++)
        
{
            
if(a[i][j]!=b[i][j])
            
{
                flag
=7;
                
break;
            }

        }

        
if(flag==7break;
    }

    
return flag;
}