算法分析课设(二)阅读下面的程序,按要求回答下面的问题

#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

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&5&4&6\\ 0&3&2&7\end{bmatrix}

max=0

min=0x7fffffff

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&6&5&4\\ 0&3&2&7\end{bmatrix}

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&6&5&4\\ 0&7&3&2\end{bmatrix}

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

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&6&5&4\\ 0&2&7&3\end{bmatrix}

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

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&6&5&4\\ 0&3&2&7\end{bmatrix}

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

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&4&6&5\\ 0&3&2&7\end{bmatrix}

num=\begin{bmatrix} 0&0&0&0\\ 0&2&3&5\\ 0&6&5&4\\ 0&7&3&2\end{bmatrix}

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;
}

猜你喜欢

转载自blog.csdn.net/qq_33514421/article/details/112297813
今日推荐