//右斜杠求积
int flag1=0;
num1=1;
for(int i=0;i<=16;i++)
for(int j=flag1/4;j<=16;j++)
{
if(flag1%4==0&&flag1!=0) {
flag1++;
if(num1>num)
num=num1;
num1=1;
break;
}
flag1++;
num1*=a[i+(flag1-1)%4][j];
}
一开始设想的斜着求积问题,尝试将每一项都单独累乘进num1,但是发现只实现了楼梯状累乘,比如第一次的四项以a[0][0]开头向右下乘四次,第二次的四项为以a[1][2]为头向下乘四次,想了6个小时后躺床上想了五分钟想出来了,问题就说我们ij都有一个局域性的改变,比如i=0时i还要能取到1,2,3,并且还要有匹配的j=0,1,2,3;那么我们直接将这种改变写成一个式子:
num1=a[i+3][j]*a[i+2][j+1]*a[i+1][j+2]*a[i][j+3];
代码直接简单起来:
//右斜杠求积
for(int i=0;i<=16;i++)
for(int j=0;j<=16;j++){
num1=a[i+3][j]*a[i+2][j+1]*a[i+1][j+2]*a[i][j+3];
if(num1>num)
num=num1;
num1=1;
}
那么完整的代码就是:
#include <math.h>
#include <stdio.h>
int main()
{
int num,num1=1;
int a[20][20]= {
8,02,22,97,38,15,00,40,00,75,04,05,07,78,52,12, 50,77,91,8,
49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48, 04,56,62,00,
81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,03, 49,13,36,65,
52,70,95,23,04,60,11,42,69,24,68,56,01,32,56,71, 37,02,36,91,
22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28, 66,33,13,80,
24,47,32,60,99,03,45,02,44,75,33,53,78,36,84,20, 35,17,12,50,
32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66, 18,38,64,70,
67,26,20,68,02,62,12,20,95,63,94,39,63,8,40,91, 66,49,94,21,
24,55,58,05,66,73,99,26,97,17,78,78,96,83,14,88, 34,89,63,72,
21,36,23,9,75,00,76,44,20,45,35,14,00,61,33,97, 34,31,33,95,
78,17,53,28,22,75,31,67,15,94,03,80,04,62,16,14, 9,53,56,92,
16,39,05,42,96,35,31,47,55,58,88,24,00,17,54,24, 36,29,85,57,
86,56,00,48,35,71,89,07,05,44,44,37,44,60,21,58, 51,54,17,58,
19,80,81,68,05,94,47,69,28,73,92,13,86,52,17,77, 04,89,55,40,
04,52,8,83,97,35,99,16,07,97,57,32,16,26,26,79, 33,27,98,66,
88,36,68,87,57,62,20,72,03,46,33,67,46,55,12,32, 63,93,53,69,
04,42,16,73,38,25,39,11,24,94,72,18,8,46,29,32, 40,62,76,36,
20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85, 74,04,36,16,
20,73,35,29,78,31,90,01,74,31,49,71,48,86,81,16, 23,57,05,54,
01,70,54,71,83,51,54,69,16,92,33,48,61,43,52,01, 89,19,67,48
};
//横乘
for(int i=0;i<20;i++){
num1=0;
int flag=0;
for(int j=0;j<20;j++) {
num1 *=a[i][j];
flag++;
if (flag==4){
if(num1>num){
num=num1;
}
flag=0;
num1=1;
}
}
}
//竖乘
for(int i=0;i<20;i++){
num1=0;
int flag=0;
for(int j=0;j<20;j++) {
num1 *=a[j][i];
flag++;
if (flag==4){
if(num1>num){
num=num1;
}
flag=0;
num1=1;
}
}
}
// 左斜杠求积 i:0,4,8,12,16
for(int i=0;i<=16;i++)
for(int j=0;j<=16;j++)
{
num1=a[i][j]*a[i+1][j+1]*a[i+2][j+2]*a[i+3][j+3];
if(num1>num)
num=num1;
num1=1;
}
//右斜杠求积
for(int i=0;i<=16;i++)
for(int j=0;j<=16;j++){
num1=a[i+3][j]*a[i+2][j+1]*a[i+1][j+2]*a[i][j+3];
if(num1>num)
num=num1;
num1=1;
}
printf("%d",num);
return 0;
}
思考总结:开始将题目片面的看成了考验算法思维的难题,想通过斜着乘去展现自己的能力,所以目光局限于单个取出然后累乘,这涉及到了i,j在0~19这个大范围要取遍,又要在每个取值之后能局限地遍历其后四位,然后又要考虑能够将ij的遍历匹配在一起,因为i与j的遍历不是同时进行的,i取定值后j在遍历,j遍历完了i才取值然后j又遍历,所以一开始我考虑多弄两个变量i1;j1,让i1<=i+3;这样去遍历四次,但是这种方法在i1与j1取值如何匹配的问题上没办法处理,因为i1固定了j1在遍历,没办法同时遍历,然后我考虑不用i1,j1去写;而是定一个flag1,flag1每次加1,第一个坐标为i+flag1%4;第二个坐标为j+flag1/4;然后每次flag1%4==0退出循环j,遍历i,但是这在执行到一些值时横纵坐标还是无法匹配的问题,所以这种方法也没办法写