算法设计与分析实验二

1

设计算法求解整数的划分问题,对给定的整数,输出划分数,并思考如何实现输出每个具体的划分。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+5;
ll arr[N];
ll sum,cnt;
ll n;
ll num=0;
void dfs(ll m){
	if(sum==n){
		num++;
		cout << "n=";
		for(ll i = 0; i < cnt - 1; i++){
			cout << arr[i] << "+";
		}
		cout << arr[cnt-1]<< endl;
	}
	if(sum>n) return;
	for(ll i=m;i>0;i--){
		sum+=i;
		arr[cnt]=i;
		cnt++;
		dfs(i);
		sum-=i;
		cnt--;
	}
}
int main(){
	cin >> n;
	dfs(n-1);
	cout << num << endl;
	return 0;
} 

思路
用dfs,记录每个具体的划分

2

设计算法求解n个互异元素的全排列的算法并编程实现(P13),并在此基础上修改程序,使其能解决有重复元素的排列问题(P42算法实现题2-5)
元素的全排列

# include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll arr[100005];
ll n;
void dfs(ll k){
	if(k==n){
		for(ll i = 0; i < n; i++){
			printf("%lld",arr[i]);
		}
		printf("\n");
	}
	else{
		for(ll i = k; i < n; i++){
			swap(arr[i],arr[k]);
			dfs(k+1);
			swap(arr[i],arr[k]);
		}
	}
}
int main(){
	scanf("%lld",&n);
	for(ll i = 0; i < n; i++){
		scanf("%lld",&arr[i]);
	}
	dfs(0);
	return 0;
}

在这里插入图片描述
思路
因为该半数集是多重集,所以是半数集问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll arr[N];
ll set1(ll n){
	if(arr[n]>0) return arr[n];
	arr[0]=arr[1]=1;
	ll sum=1;
	for(ll i=1; i<=n/2;i++){
		sum+=set1(i);
	}
	arr[n]=sum;
	return sum;
}
int main(){
	ll n;
	cin >> n;
	ll sum = set1(n);
	cout << sum << endl;
	return 0;
}

考虑到半数单集问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll arr[N];
ll set1(ll n){
	if(arr[n]>0) return arr[n];
	arr[0]=arr[1]=1;
	ll sum=1;
	for(ll i=1; i<=n/2;i++){
		sum+=set1(i);
		if(i>10&&i/10 <= (i%10)/2) sum-=set1(i/2);
	}
	arr[n]=sum;
	return sum;
}
int main(){
	ll n;
	cin >> n;
	ll sum = set1(n);
	cout << sum << endl;
	return 0;
}

3

设计算法求解特殊棋盘的覆盖问题,并编程实现(P20)。

#include<bits/stdc++.h>
using namespace std;
int Board[100][100];
int tile=1;

void ChessBoard(int tr,int tc,int dr,int dc,int size)
{
	if(size == 1)
	{
		return;
	}
	int t = tile++;//L型骨牌编号
	int s = size/2;//分割棋盘

	//覆盖左上角子棋盘
	if(dr<tr+s && dc<tc+s)//特殊方格在此棋盘中
	{
		ChessBoard(tr,tc,dr,dc,s);
	}
	else//特殊方格不在此棋盘中
	{
		//用编号为t的骨牌覆盖右下角
		Board[tr+s-1][tc+s-1] = t;
		//覆盖其余方格
		ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
	}

	//覆盖右上角子棋盘
	if(dr<tr+s && dc>=tc+s)//特殊方格在此棋盘中
	{
		ChessBoard(tr,tc+s,dr,dc,s);
	}
	else//特殊方格不在此棋盘中
	{
		//用编号为t的骨牌覆盖左下角
		Board[tr+s-1][tc+s] = t;
		//覆盖其余方格
		ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
	}

	//覆盖左下角子棋盘
	if(dr>=tr+s && dc<tc+s)//特殊方格在此棋盘中
	{
		ChessBoard(tr+s,tc,dr,dc,s);
	}
	else//特殊方格不在此棋盘中
	{
		//用编号为t的骨牌覆盖右上角
		Board[tr+s][tc+s-1] = t;
		//覆盖其余方格
		ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
	}

	//覆盖右下角子棋盘
	if(dr>=tr+s && dc>=tc+s)//特殊方格在此棋盘中
	{
		ChessBoard(tr+s,tc+s,dr,dc,s);
	}
	else//特殊方格不在此棋盘中
	{
		//用编号为t的骨牌覆盖左上角
		Board[tr+s][tc+s] = t;
		//覆盖其余方格
		ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
	}

}
int main(){
	int n;
	cin >> n;//棋盘宽度 
	int x,y;
	cin >> x >> y;//特殊棋子的位置 
	ChessBoard(1,1,x,y,n);
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= n; j++){
			printf("%4d",Board[i][j]);
		}
		cout << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值