题目描述:
假设有个大小为n*n的图片,然后有若干变换方式:不变、逆时针旋转、左右对称、只有上半部分左右对称、只有下半部分上下对称、把偶数行压到上半部分且把奇数行压到下半部分、混合。和这些变换的逆(比如逆时针旋转反过来就是顺时针旋转)。
现给出一组这些变换的组合,问这个组合最少要执行多少次才能使图片和原来一样。
输入,图片边长n,变换的组合。
输出,最小需要的次数。
解题思路:
构造一个矩阵并给每个点编号,把最开始的那组置换模拟一遍,便得出经过一组变换后每个点能到达哪里。然后从每个点搜经过多少次变换能到达原来的位置。然后求它们的最小共倍数即可。
题目本身不难,但模拟得真心烦,而且输入格式也很奇葩,那组变换要倒着来。而且gets AC、getline WA,这是为什么呢?
代码供参考:
#include<cstdio>
#include<sstream>
#include<cstring>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
void get(int v,int &x,int &y,int n){
x=v/n;y=v%n;
}
void id(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[i][j]=a[i][j];
}
}
}
void ret(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int x,y;
get(a[i][j],x,y,n);
res[x][y]=i*n+j;
}
}
}
void rot(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[n-j-1][i]=a[i][j];
}
}
}
void rot_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[i][j]=a[n-j-1][i];
}
}
}
void sym(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[i][j]=a[i][n-1-j];
}
}
}
void sym_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[i][n-i-j]=a[i][j];
}
}
}
void bhsym(int a[][1100],int res[][1100],int n){
for(int i=0;i<n/2;i++){
for(int j=0;j<n;j++){
res[i][j]=a[i][j];
}
}
for(int i=n/2;i<n;i++){
for(int j=0;j<n;j++){
res[i][j]=a[i][n-1-j];
}
}
}
void bhsym_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n/2;i++){
for(int j=0;j<n;j++){
res[i][j]=a[i][j];
}
}
for(int i=n/2;i<n;i++){
for(int j=0;j<n;j++){
res[i][n-1-j]=a[i][j];
}
}
}
void bvsym(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
if(i<n/2)for(int j=0;j<n;j++)res[i][j]=a[i][j];
else{
for(int j=0;j<n;j++){
res[i][j]=a[3*n/2-i-1][j];
}
}
}
}
void bvsym_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
if(i<n/2)for(int j=0;j<n;j++)res[i][j]=a[i][j];
else{
for(int j=0;j<n;j++){
res[3*n/2-i-1][j]=a[i][j];
}
}
}
}
void div(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i%2)res[i/2+n/2][j]=a[i][j];
else res[i/2][j]=a[i][j];
}
}
}
void div_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i%2)res[i][j]=a[i/2+n/2][j];
else res[i][j]=a[i/2][j];
}
}
}
void mix(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i%2==0){
if(j%2==0)res[i][j]=a[i][j/2];
else res[i][j]=a[i+1][j/2];
}else{
if(j%2==0)res[i][j]=a[i-1][n/2+j/2];
else res[i][j]=a[i][n/2+j/2];
}
}
}
}
void mix_(int a[][1100],int res[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i%2==0){
if(j%2==0)res[i][j/2]=a[i][j];
else res[i+1][j/2]=a[i][j];
}else{
if(j%2==0)res[i-1][n/2+j/2]=a[i][j];
else res[i][n/2+j/2]=a[i][j];
}
}
}
}
void print(int a[][1100],int n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%2d ",a[i][j]);
}
printf("\n");
}
}
char str[300];
char s[20];
int a[1100][1100],res[1100][1100];
bool vis[1100][1100];
long long gcd(long long x,long long y){return y?gcd(y,x%y):x;}
int main(){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);getchar();
gets(str+1);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a[i][j]=i*n+j;
}
}
str[0]=' ';
int len=strlen(str+1);
str[len+1]=' ';
int o=0;
int j;
for(int i=len;i>=0;i--){
if(str[i]==' '){
for(j=i+1;str[j]!=' '&&str[j]!='-';j++)
s[j-i-1]=str[j];
s[j-i-1]='\0';
if(strcmp(s,"id")==0){
id(a,res,n);
}else if(strcmp(s,"rot")==0){
if(o==1){
rot(a,res,n); id(res,a,n);
rot(a,res,n); id(res,a,n);
}
rot(a,res,n);
id(res,a,n);
}else if(strcmp(s,"sym")==0){
sym(a,res,n);id(res,a,n);
} else if(strcmp(s,"bhsym")==0){
bhsym(a,res,n);id(res,a,n);
}else if(strcmp(s,"bvsym")==0){
bvsym(a,res,n);id(res,a,n);
}else if(strcmp(s,"div")==0){
if(o==0){div(a,res,n);id(res,a,n);}
else {div_(a,res,n);id(res,a,n);}
}else if(strcmp(s,"mix")==0){
if(o==0){mix(a,res,n);id(res,a,n);}
else {mix_(a,res,n);id(res,a,n);}
}
o=0;
}
if(str[i]=='-')o=1;
}
long long mul=1;
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
long long len=0;
if(vis[i][j])continue;
else{
int x=i,y=j;
while(vis[x][y]==false){
vis[x][y]=true;
len++;
get(a[x][y],x,y,n);
}
mul=mul*(len/gcd(mul,len));
}
}
}
printf("%lld\n",mul);
if(T)printf("\n");
}
一个打表的代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
string a[14]={"id","id-","rot","rot-","sym","sym-","bhsym","bhsym-","bvsym","bvsym-","div","div-","mix","mix-"};
int main(){
int T=100;
freopen("data.in","w",stdout);
printf("%d\n",T);
for(int i=0;i<T;i++){
if(i)cout<<endl;
printf("1024\n");
for(int j=0;j<5;j++){
if(!j)cout<<a[rand()%14];
else cout<<" "<<a[rand()%14];
}
cout<<endl;
}
}