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