UVALive 3510 Pixel Shuffle

http://livearchive.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1511

题目描述:

假设有个大小为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;
	}
}



PixelShuffle是Pytorch中的一个函数,用于将输入的张量进行像素重排。它的实现方式是通过将输入的通道进行重新排列,形成更高分辨率的输出张量。具体来说,PixelShuffle函数接受一个参数r,表示每个输出像素包含的输入通道数量。例如,如果r=2,那么每个输出像素将由4个输入通道组成。 在Pytorch中,可以使用torch.nn.PixelShuffle(upscale_factor)来调用PixelShuffle函数来实现像素重排。其中,upscale_factor表示放大倍数,即每个输出像素包含的输入通道数量。 以输出张量的(0, 0)位置的像素为例,它对应了r^2个通道。这些通道会被排列成一个r x r的大像素。例如,如果r = 3,那么输出张量的一个像素将包含9个通道。这个像素对应于右边SR图像中一个3x3的大像素。值得注意的是,颜色的对应关系需要仔细观察,以确保正确的像素匹配。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [PixelShuffle原理笔记(paper,pytorch实现)](https://blog.csdn.net/level_code/article/details/123637969)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [低分辨率feature maps的上采样方法:pixelshuffle](https://blog.csdn.net/qq_38883271/article/details/116260821)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值