小言_互联网的博客

旋转函数(移位加密)C语言 --算法学习

344人阅读  评论(0)

旋转函数(移位加密)

题目:

给定一个长度为 n 的整数数组A。假设Bk是数组A顺时针旋转k个位置后的数组,我们定义A的“旋转函数”F为:
F(k) = 0 * Bk[0] + 1 * Bk[1] + … + (n-1) * Bk[n-1]。
计算F(0), F(1), …, F(n-1)中的最大值。
示例:
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
所以F(0),F(1),F(2),F(3)中的最大值是F(3) =26。

直接看代码

#include<stdio.h>
#include<string.h>
int main()
{
	int a[100];
	int i,j,k,x,N,s;
	int C[100]={0};
	int max=-99999;//开始设置一个最大值为一个非常小的数
	
	int R[100]={0};//定义多个数组作为中间变量
	int z[100]={0};
	int v[100]={0};
	int m[100] = {0};
	
	printf("请输入数组元素个数:\n");
	scanf("%d",&N);
	printf("请输入数组元素:\n");
	
	for(i=0;i<N;i++)//循环录入
	{
		scanf("%d",&m[i]);
	}
	
	
	   
	   for(i=0;i < N;i++)//计算F(n)的
	   {
		   
		   //下面循环是对数组进移位
		  // 解释:z[j] = m[(i + j) % N];	
		   /*
		     在i=0时,就是所有的数向后移动0个位置
				z0=m[0+0]
				z1=m[0+1]
				……
			i=1时 就是所有的数向后移动1个位置
				z[j]=m[i+j]
				z[0]=m[1+0]=m[1]
				z[1]=m[1+1]=m[2]
				z[2]=m[1+2]=m[3]
				z[3]=m[1+3]=m[4]
				如果i+j 超过了输入数的个数,就用个数取余,回到第一个数;
			如果有5个数,
				z[4]=m[1+4]:但是没有m[5]这个数(5个数是从0——4)
				所以就对1+4用5取余,得到零
				z[4]=m[(1+4)%5]=m[0]
		   */
	   		for(j = 0; j < N; j++)
	   		{
	   			z[j] = m[(i + j) % N];	
	   		}
			
			
			//下面的循环计算出:
		    //(0 * m[0])
			//(1 * m[1])
			//(2 * m[2])
			//(3 * m[3])
			//(4 * m[4])
			//保存在v数组中。
			
		   for(j=0;j<N;j++)//计算
		   {
			v[j] = (j * z[j]);
		   
		   	R[i] += v[j];//累加求和,算出F(i)
			
			}
			
			//如果现在的函数值比之前记录的最大值大,就更新最大值
			if(max<R[i])
			{
				max=R[i];
			}
		}
		
	   printf("\n\n");
	   
	   //这个是输出表达式,可以不用写,核心思想和上面一样
	   for(j=0;j<N;j++)
		{
			printf("F(%d)=",j) ; //j*a[N]+j*a[N-1]
			for(k=0;k<N;k++)
		   {
			   if(k == 0)//说明是第一个式子,前面没有+
			   {
					printf("(%d * %d)",k,m[(k+j)%(N)]);
				}
				if(k>0 && k<N)//从第二个式子开始,每个之前加一个+
				{
					printf("+(%d * %d)",k,m[(k+j)%(N)]);
				}
			}
			printf("=%d.",R[j]);
			printf("\n");
		   }
		  printf("\n\n");
		  
		  //输出之气那记录的最大值
		  
		  printf("\n最大值为:%d",max);
		   return 0;
   }

运行之后会发现之顺序有问题:

题目要求:
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26

理解了思想之后,在稍微再取余做一点操作就可以了

m[(j+i) % N]这个会逆时针移动
只要改成:
m[(j-i+N) % N]
就可以顺时针移动

	for(j = 0; j < N; j++)
	   		{
	   			z[j] = m[(j-i+N) % N];	
	   		}
			 if(k == 0)//说明是第一个式子,前面没有+
			   {
					printf("(%d * %d)",k,m[(j-i+N) % N]);
				}
				if(k>0 && k<N)//从第二个式子开始,每个之前加一个+
				{
					printf("+(%d * %d)",k,m[(j-i+N) % N]);
				}


转载:https://blog.csdn.net/weixin_44494648/article/details/102575266
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场