旋转函数(移位加密)
题目:
给定一个长度为 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