Algorithm Design and Analysis Course Design

Foreword: I don't have time to write, I just wrote the code, I can't guarantee that it's all right, and the questions I pick are all simple. The backtracking question was written incorrectly by myself, and I found someone else's to write it.

Divide and conquer:

3. Integer factorization

A positive integer n greater than 1 can be decomposed into: n=x1×x2×…×xm.

For example, when n=12, there are 8 different decompositions:

12=12

12=6×2

12=4×3

12=3×4

12=3×2×2

12=2×6

12=2×3×2

12=2×2×3

enter:

The data has multiple rows, given a positive integer (a positive integer less than 10000000)

output: 

Each data output is a row, which is the number of different decompositions of the positive integer n.

input sample

12

35

Sample output

8

3

#include<iostream>
#include<stdio.h>
using namespace std;
int resolve(int n)
{
	int count = 1, i;					// ans = 1初始表示n = n的情况
	for (i = 2; i * i < n; i++){
        if (n % i == 0)				// i 是 n的因子, n / i也是n的因子
			count += resolve(i) +resolve(n / i);
    }		
	if (i * i == n)					// i是n的因子, 并且i * i == n时只有这一种情况, 左右交换也是一种
		count += resolve(i);
	return count;
}

int main()
{
	int n;
	while(scanf("%d",&n)!=-1){
		cout<<resolve(n);
	}
	
	return 0;
}

dynamic programming

4. Step problem

Description of the problem: There are n steps, a person goes up one or two steps at a time, and asks how many ways to complete the n steps.

Actual situation: Given a matrix m, starting from the upper left corner, you can only go right or down each time, and finally reach the lower right corner. The sum of all numbers in the path is the path sum, and the minimum path sum of all paths is returned, If m is given as follows, then paths 1,3,1,0,6,1,0 are the minimum path sums, returning 12.

1 3 5 9

8 1 3 4

5 0 6 1

8 8 4 0

 

 

#include<iostream>
using namespace std;
const int N=10;
int m[N][N];
int main(){ 
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>m[i][j];
        }
    }
    int dp[n][n]={0};
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            dp[i][j]=m[i][j];
        }
    }
    for(int i=1;i<n;i++){
        dp[i][0]+=dp[i-1][0];
    }
    for(int j=1;j<n;j++){
        dp[0][j]+=dp[0][j-1];
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<n;j++){
            dp[i][j]+=min(dp[i-1][j],dp[i][j-1]);
        }
    }

    cout<<dp[n-1][n-1]<<endl;
    int i=0,j=0;
    cout<<m[i][j]<<" ";
    while(true){
        if(i==n-1&&j==n-1){
            break;
        }
        if(dp[i+1][j]>dp[i][j+1]){
            cout<<m[i][j+1]<<" ";
            j++;
        }
        else{
            cout<<m[i+1][j]<<" ";
            i++;
            
    }

}
}
// 1 3 5 9
// 8 1 3 4
// 5 0 6 1
// 8 8 4 0

greedy

1. File connection problem: Given an array F of size n, the array element F[i] represents the length of the ith file. Now all files need to be merged into one file. The longer the file is, the longer it takes to connect to a new file. Try to give a greedy algorithm to give the file connection order to ensure that the time spent connecting files is the shortest. 

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100;
// 文件连接问题:给定一个大小为n的数组F,数组元素F[i]表示第i个文件的长度。
// 现在需要将所有文件合并成一个文件,
// 文件越长后面连接成新文件花费的时间越长,试给出贪心算法给出文件连接顺序,
// 保证连接文件花费的时间最短。
int main(){
    int n;
    cin>>n;
    int F[N],P[N];
    for(int i=0;i<n;i++){
        cin>>F[i];
    }
    for(int i=0;i<n;i++){
        P[i]=F[i];
    }
    sort(P,P+n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(P[i]==F[j]){
                cout<<j+1<<" ";
            }
        }
    }

}
// 5 8 1 3 4 9

 

Traceback:

1. The prime number ring problem

(1) Problem description: Input a positive integer n, and form a ring of integers 1, 2, 3, 4...n, so that the sum of two adjacent integers is a prime number.

(2) Sample

enter:

6

output:

1 4 3 2 5 6

1 6 5 2 3 4

(3) Hint: the search solution space tree when n=4.

 

#include<iostream>
#include<cmath>
using namespace std;
int n=0;
const int N=105;
int a[N];       //对应环 
int visit[N]={-1};  //标记数组 0表示未用 1表示已用 
int check(int k)  //判断数字x是否为素数 
{
	int i,n;
	n=(int)sqrt(k);
	for(i=2;i<=n;i++)
		if(k%i==0) return 0;
	return 1;     		
}
void dfs(int step)
{
	if(step==n&&check(a[0]+a[n-1])==1) //全部填满而且第一个元素和最后一个元素满足就输出 
	{
		for(int i=0;i<n;i++)
			cout<<a[i]<<" ";
			cout<<endl;
			return ;
	}
	else
	{
		for(int i=2;i<=n;i++)
		{
			if(visit[i]==0&&check(i+a[step-1])==1){    //i没有被占用且与前一个元素符合 
				a[step]=i;
				visit[i]=1;
				dfs(step+1);
				visit[i]=0;
			}
		}
	}
	
}
int main(void)
{
	cin>>n;
	a[0]=1;  //因为是环所以第一个元素固定 
	visit[1]=1; //1已用 
	dfs(1);	//从第一个元素开始 
	return 0;	
} 

 

Guess you like

Origin blog.csdn.net/qq_56350439/article/details/124768014