#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int n,max,min,sum;
int num[10][10];
// 原题的输入参数是m,这里为了方便观察,改成了k
void move(int k)
{
int a,i;
a=num[k][n];
for(i=n-1;i>=1;i--){
num[k][i+1]=num[k][i];
}
num[k][1]=a;
}
void dfs(int k)
{
int i,j;
if(k==n+1){
max=0;
for(i=1;i<=n;i++){
sum=0;
for(j=1;j<=n;j++)
sum=sum+num[j][i];
if(sum>max)
max=sum;
}
if(max<min)
min=max;
return;
}
for(i=1;i<=n;i++){
move(k);
dfs(k+1);
}
}
int main()
{
int i,j;
while((scanf("%d",&n)!=EOF)&&(n!=-1)) {
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&num[i][j]);
max=0;
min=0x7fffffff;
dfs(2);
printf("%d\n",min);
}
return 0;
}
(1)在输入下面的数据时,求程序的输出结果,写出求解过程中变量的变化。
3
2 3 5
5 4 6
3 2 7
-1
n=3
max=0
min=0x7fffffff
max=0
sum=2+6+7=15
max=15
sum=0
sum=3+5+3=11
sum=0
sum=5+4+2=11
min=15
max=0
sum=2+6+2=10
max=10
sum=0
sum=3+5+7=15
max=15
sum=0
sum=5+4+3=12
max=0
sum=2+6+3=11
max=11
sum=0
sum=3+5+2=10
sum=0
sum=5+4+7=16
max=16
min=11
max=0
sum=2+6+7=15
max=15
sum=0
sum=3+5+3=11
sum=0
sum=5+4+2=11
后面还有6次移位。。懒得写了
(2)分析函数dfs的时间复杂度,写出分析过程。
dfs是递归函数,主要包含结束条件、数据处理和自身调用。每次调用dfs时,它首先会进行结束条件的判断,如果没有结束,则进行数据处理和自身调用;如果结束则计算最值后返回空。这里比较难理解的是,数据处理和自身调用是放在一个n次循环里面的。但是由于在每次调用dfs时,判断条件之一n不会改变,判断条件之二k也不会有改变,所以这个图每次dfs的调用我们只用k标出来。它的复杂度如图所示。
下面是进行注释后的代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// n代表数字矩阵的规模
int n,max,min,sum;
int num[10][10];
// 在数字矩阵的第m行,从第2列开始向右移动一个单位
void move(int k)
{
int a,i;
a=num[k][n];
// 在m+1行从第2列开始向右移动1个单位
for(i=n-1;i>=1;i--){
num[k][i+1]=num[k][i];
}
// m+1行的第二列设置为移位之前二维数组右下角的值
num[k][1]=a;
}
// 计算每一列总和的最大值最小值
void dfs(int k)
{
int i,j;
// k到最后一行了
if(k==n+1){
max=0;
// 遍历n列
for(i=1;i<=n;i++){
// 每列的总和
sum=0;
// 遍历每列的n行
for(j=1;j<=n;j++)
// 每列的总和
sum=sum+num[j][i];
// max保存和最大的那一列
if(sum>max)
max=sum;
}
// 更新min
if(max<min)
min=max;
return;
}
for(i=1;i<=n;i++){
// 移动k行
move(k);
dfs(k+1);
}
}
int main()
{
int i,j;
// 输入n,以-1结束
while((scanf("%d",&n)!=EOF)&&(n!=-1)) {
// 进行n*n的循环,输入二维数组num
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&num[i][j]);
// 设置初始最大最小值
max=0;
min=0x7fffffff;//代表int的最大值
// 从第二行开始移动
dfs(2);
printf("%d\n",min);
}
return 0;
}