浅析洛谷P4924(一道普及/提高-的题目)的解决方法

题目描述:
Scarlet最近学会了一个数组魔法,她会在n×n二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转90°。首先,Scarlet会把1到n^2的正整数按照从左往右,从上至下的顺序填入初始的二维数组中,然后她会施放一些简易的魔法。
Scarlet既不会什么分块特技,也不会什么Splay套Splay,她现在提供给你她的魔法执行顺序,想让你来告诉她魔法按次执行完毕后的二维数组。
输入格式:
第一行两个整数n,m,表示方阵大小和魔法施放次数。接下来m行,每行44个整数x,y,r,z,表示在这次魔法中,Scarlet会把以第x行,第y列为中心的2r+1阶矩阵按照某种时针方向旋转,其中z=0表示顺时针,z=1表示逆时针。
输出格式:
输出n行,每行有n个用空格隔开的数,表示最终所得的矩阵
说明/提示:
对于50%的数据,满足r=1
对于100%的数据1≤n,m≤500,满足1 ≤ x – r ≤ x + r ≤ n, 1 ≤ y – r ≤ y + r ≤ n.
样例输入
5 4
2 2 1 0
3 3 1 1
4 4 1 0
3 3 2 1
输出
5 10 3 18 15
4 19 8 17 20
1 14 23 24 25
6 9 2 7 22
11 12 13 16 21
思路分析:
由于上学期我在学校的oj上做过一道图像旋转的题(操作就是把一个m×n的矩阵顺时针旋转90°),所以在刚看到这道题的时候,我想的是用之前的思路,把它定义成一个函数,然后逆时针旋转90°可以看做是使用三次那个函数(后来发现还有很多细节要处理)。根据每一次所给的r[i],可以确定出需要旋转的矩阵所在行和列的范围,也就是边界,对它用所定义的函数即可。
求解过程的说明:
代码是用C语言编写的。
第一次在定义函数的过程中出现了问题,主要是C语言中return不能直接返回一个数组,需要借助指针,通过返回对应类型指针的方式,返回数组。
于是第二次我就直接把这个过程写到主函数里面了,然后这个时候如果再用顺时针旋转270°的方式来表示逆时针旋转90°会有些繁琐,所以更改为直接寻找顺时针旋转90°和逆时针旋转90°的规律,分别进行。通过探究发现,对于n×n的矩阵中的任意一个元素a[i][j],顺时针旋转90°后,它的行和列相应的变为j,n-i-1(由于是从第0行,第0列开始,所以用n-1减i),逆时针旋转90°后,它的行和列相应的变为n-j-1,i。然后在本地测试了样例,发现还是存在一些问题。调试之后发现了两个问题:
第一,如果只用一个二维数组a的话,没有办法存储临时变量,这在输出中表示为1-25中的数字有的会出现多次;
第二,矩阵的一部分旋转和整体进行旋转是不完全一样的(一开始我以为是一样的),比如对5×5的矩阵(元素为题目要求那样输入)的左上角的3×3的矩阵进行逆时针旋转90°,那么1由在a[0][0]的位置变为在a[2][0]的位置上,但整体旋转却是转到a[4][0]的位置。
基于此,我进行了第三次的尝试:先是定义另一个二维数组b来存储a的每一次变换之后的元素,然后对于部分旋转矩阵的问题,可以看做是一个2r+1阶的矩阵通过平移后对应a的行与列,这样2r+1阶的矩阵就是一个对自己的整体旋转,符合上面找到的行与列的变换规律。然后本地过了之后一次就AC了。

#include<stdio.h>
int main()
{
	int n,m,i,j,k,a[500][500]={0},b[500][500]={0},x[500],y[500],r[500],z[500],t=1;
	scanf("%d %d",&n,&m);
	for(i=0;i<m;i++)
	{
		scanf("%d %d %d %d",&x[i],&y[i],&r[i],&z[i]);	
	}
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			a[i][j]=t;b[i][j]=t;
			t++;
		}
	}
	for(i=0;i<m;i++)
	{
		if(z[i]==1)
		{
			for(j=0;j<=2*r[i];j++)
			{
				for(k=0;k<=2*r[i];k++)
				{
					b[j+x[i]-r[i]-1][k+y[i]-r[i]-1]=a[k+x[i]-r[i]-1][y[i]+r[i]-j-1];
				}
			}
		}
		if(z[i]==0)
		{
			for(j=0;j<=2*r[i];j++)
			{
				for(k=0;k<=2*r[i];k++)
				{
					b[j+x[i]-r[i]-1][k+y[i]-r[i]-1]=a[x[i]+r[i]-k-1][y[i]-r[i]+j-1];
				}
			}
		}
		for(j=x[i]-r[i]-1;j<x[i]+r[i];j++)
		{
			for(k=y[i]-r[i]-1;k<y[i]+r[i];k++)
			{
				a[j][k]=b[j][k];
			}
		}	
	}
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			printf("%d ",b[i][j]);
		}
		printf("\n");
	}
	return 0;
}
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
enctype="multipart/form-data" 是在HTML中用于指定表单数据提交的编码类型。它被用于在表单中上传文件时。 当表单中包含文件上传时,使用multipart/form-data编码类型可以确保文件能够正确地被传递到服务器。这种编码类型将表单数据和文件一起作为多部分消息进行编码,并且每个控件对应消息中的一个部分。这样可以确保文件的二进制数据能够正确地被传输。 在HTML中,可以通过在form标签中设置enctype属性为"multipart/form-data"来指定表单的编码类型为multipart/form-data。例如,可以使用MVC的Html.BeginForm()方法来生成带有正确编码类型的表单代码。 总结来说,enctype="multipart/form-data" 是用于在HTML表单中指定文件上传时的编码类型,确保文件能够正确地被传递到服务器。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [上传文件fileupload+解决enctype= multipart/form-data无法传递其他参数](https://download.csdn.net/download/benbenbzq/9136901)[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: 33.333333333333336%"] - *2* [js动态在form上插入enctype=multipart/form-data的问题](https://download.csdn.net/download/weixin_38702110/14903958)[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: 33.333333333333336%"] - *3* [浅析application/x-www-form-urlencoded和multipart/form-data的区别](https://download.csdn.net/download/weixin_38741075/13727017)[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: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值