模拟 poj 3106 Flip and Turn
来源:互联网 发布:工商银行数据中心待遇 编辑:程序博客网 时间:2024/05/17 02:11
题目链接:
http://poj.org/problem?id=3106
题目大意:
有一个m*n的矩阵,有10种操作,给一个操作串,求最后的矩阵。
操作'1' :沿主对角线翻转 行列交换
操作‘2’:沿副对角线翻转 行列交换
操作‘H':沿水平方向翻转
操作’V‘:沿竖直方向翻转
操作’A‘:顺时针旋转90度,’B':顺时针旋转180度,‘C'顺时针旋转270度。除180度行列不交换外,其他两种行列交换
操作’X‘:逆时针旋转90度,’Y‘:逆时针旋转180度,’Z‘逆时针旋转270度。除180度行列不交换外,其他两种行列交换
操作字符串最多有100000个,如果每一个操作都对矩阵的每个元素进行,肯定会超时。所以就会想到,如果把所有的操作都统一处理成简单的几种操作,最后等价处理后,再对矩阵进行一次操作,就会很简单,也不会超时。
关键是找等价关系,并且能够用数学语言等价描述。我的想法是,将十种操作都对应成H,V,和A三种操作,对每一个操作都转化成HVA的方式。
很显然有如下关系:H和V最多出现一个,因为H+V(先水平翻转再竖直翻转)=V+H(先竖直翻转再水平翻转)=A*2(顺时针旋转90度两次)。H+H=0(先水平翻转再水平翻转等于本身)同理:V+V=0 所以最后的结果集只可能是00a,01a,10a(a表示顺时针旋转90度的次数)
对于操作’1‘:等价于先逆时针旋转90度再H一次<=>先H再顺时针旋转90度一次。 XH=HA
对于操作’2‘:等价于先顺时针旋转90度再H一次<=>先H再逆时针旋转90度一次。AH=HX
对于操作’H‘:直接和前面的等价关系**a中的a(顺时针旋转90度的次数)组合成AH=HX,一直递推到V,a次顺时针全部转化为a次顺时针。
对于操作’V‘:XV=VA=AH=HX
对于’A‘,’B‘,’C‘直接加到顺时针次数上。
对于’X‘,’Y‘,’Z‘直接减到顺时针次数上。
所以用三个变量hh,vv,shun表示水平翻转次数,竖直翻转次数,顺时针旋转次数,注意是有顺序的。
XV=AH=HX AV=XH=HA
扫描每个操作,等价处理,不满足该顺序的借助等价关系改变顺序,保持该顺序不变。
详细解释代码:
#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<string.h>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 330#define M 110000char a[Maxn][Maxn],b[Maxn][Maxn];char ord[M];int m,n;void funh() //执行水平操作{ for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[m-i+1][j]=a[i][j]; memcpy(a,b,sizeof(b));}void funv() //执行竖直操作{ for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[i][n-j+1]=a[i][j]; memcpy(a,b,sizeof(b));}void funa() //执行顺时针旋转90度操作{ for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[j][m-i+1]=a[i][j]; swap(n,m); memcpy(a,b,sizeof(b));}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d",&m,&n)) { for(int i=1;i<=m;i++) scanf("%s",a[i]+1); scanf("%s",ord); int hh=0,ss=0; //hh表示水平翻转次数,ss表示竖直翻转次数 int shu=0,len=strlen(ord); //shu表示顺时针旋转次数 int flag=0; for(int i=0;i<len;i++) { switch(ord[i]) { case '1': { flag^=1; //行列交换 //由 XH=HA 和 AH=HX if(shu) //如果之前有顺时针旋转 shu=(-shu+4)%4; //顺时针全部转化为逆时针 shu=(shu+1)%4; //最后还有个A if(hh) //H+H=0 hh=0; else if(ss) //V+H=AA { hh=0; ss=0; shu=(shu+2)%4; } else //H=0 V=0时H=1 hh++; } break; case '2': { flag^=1; //HX if(shu) shu=(-shu+4)%4; shu=(shu-1+4)%4; //最后有一个X if(hh) hh=0; else if(ss) { hh=0; ss=0; shu=(shu+2)%4; } else hh++; } break; case 'V': { if(shu) //AV=XH=HA { shu=(-(shu-1)+4)%4; shu=(shu+1)%4; //最后有一个A if(ss) { ss=0; hh=0; shu=(shu+2)%4; } else if(hh) hh=0; else hh++; break; } if(ss) { ss=0; hh=0; //shu=(shu+2)%4; } else if(hh) { ss=0; hh=0; shu=(shu+2)%4; } else ss++; //如果一个H和V都没有,ss++ } break; case 'H': { if(shu) shu=(4-shu)%4; if(ss) { ss=0; hh=0; shu=(shu+2)%4; } else if(hh) hh=0; else hh++; } break; case 'A': shu=(shu+1)%4;flag^=1;break; case 'B': shu=(shu+2)%4;break; case 'C': flag^=1;shu=(shu+3)%4;break; case 'X': flag^=1;shu=(shu-1+4)%4;break; case 'Y': shu=(shu-2+4)%4;break; case 'Z': flag^=1;shu=(shu-3+4)%4;break; } } //printf("flag:%d hh:%d ss:%d shu:%d\n",flag,hh,ss,shu); if(hh) //注意执行顺序 H V a funh(); else if(ss) funv(); if(shu) //顺时针旋转次数 { while(shu--) funa(); } /*if(flag) swap(n,m);*/ printf("%d %d\n",m,n); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) printf("%c",a[i][j]); putchar('\n'); } } return 0;}
- 模拟 poj 3106 Flip and Turn
- POJ 3106Flip and Turn(模拟)
- POJ 3106 Flip and Turn 模拟 分析
- POJ 3106 Flip and Turn
- Poj 3106 Flip and Turn(模拟+优化)
- POJ 3106 Flip and Turn 笔记
- POJ 3106 Flip and Turn <卡时间题目〉
- 模拟+搜索poj 1063 Flip and Shift
- poj 1063 Flip and Shift
- POJ 1063 - Flip and Shift
- ACM学习-POJ-1063-Flip and Shift
- ACM学习-POJ-1063-Flip and Shift
- [zz]Flip and Shift -- POJ 1063 解题报告
- POJ 1063 Flip and Shift(找规律题)
- poj 1063 Flip and Shift 冒泡排序的扩展运用
- POJ 1063 Flip and Shift 已被翻译
- Flip and Shift(ZJU_1028)
- zoj1028 Flip and Shift
- C++/CLI学习笔记1—新的托管类型
- ACM(048)小明的调查作业(1)
- Env setup for MAC OS X
- AOJ 0118 Property Distribution (BFS)
- 【黑马程序员】Java7K面试题20:交通灯管理系统
- 模拟 poj 3106 Flip and Turn
- 有实际开发工作经验
- Server gl was unable to start within 60 seconds. If the server requires more time, try increasing th
- c#编程方式触发单击事件
- myeclipse 问题
- Leetcode: Combinations
- 老船长的航海日记:ffmpeg的旅程(三)
- filter 和 servlet 中设置编码的问题
- 网络通讯合并数据发送的重要性和实现原理