数据结构与算法实验1——递归练习

1.实验内容

实验1.1

现有一个有n个元素的序列a=[a1,a2,⋯,an],定义这个序列的价值为1*a1+2*a2+…+n*an,空序列的价值为0。先给你一个长度为n的序列a,求a中所有子集价值的异或和,要求子集中元素的相对位置保持不变.

实验1.2

现有一个有n个元素的序列a=[a1,a2,⋯,an],定义其价值为a1⊕1+a2⊕2+…+an⊕n,给出这样一个序列,求其所有排列的价值vi的或.

2.测试结果

实验1.1

输入:

2

1 2

输出:

6

实验1.2

输入:

3

1 2 3

输出:

6

3.源代码

①实验1.1

#include<iostream>

using namespace std;

template <class T>

void sumSubset(T *array,int m,int n,bool *exist,T *arraySubset,int *S)

//数组array记录所有元素

//m为已判断是否存在的元素个数

//n为元素总个数

//数组exist记录子集是否包含某个元素

//数组ARRAY记录某个子集中的元素

//地址S用于记录异或和

{

if(m>=0&&m<n)

{

exist[m]=1; sumSubset(array,m+1,n,exist,arraySubset,S);

exist[m]=0; sumSubset(array,m+1,n,exist,arraySubset,S);

}

if(m==n) //所有exist均已赋值

{

int j=0,sum=0; //j用于计数该子集中的各元素,sum用于记录该子集的价值

for(int i=0;i<n;i++)

{

if(exist[i])

{

arraySubset[j]=array[i];            //将子集的第j项赋值为array[i]

j++;

}

}

for(int k=0;k<j;k++) sum+=arraySubset[k]*(k+1);

(*S)^=sum; //将异或和计入S

}

}

int main()

{

int n;     //n为序列中元素个数

cin>>n;

int *a=new int[n];

int *b=new int[n];

bool *e=new bool[n];

int *ADD=new int(0);

for(int i=0;i<n;i++) cin>>a[i];         //输入序列

sumSubset(a,0,n,e,b,ADD);

cout<<*ADD<<endl;

delete []a;

delete []b;

delete []e;

delete []ADD;

return 0;

}

②实验1.2

#include<iostream>

using namespace std;

template <class T>

void swap(T *a,T *b) //swap函数用于交换两个变量的值

{

T temp=*a;

*a=*b;

*b=temp;

}

void Nor(int array[],int m,int n,int *S)

//数组array用于存放元素

//m为已排列元素个数

//n为总元素个数

//地址S用于记录或值

{

if(m>=0&&m<n)

for(int i=m;i<n;i++)

{

swap(array[i],array[m]); //交换第m项与后面的每一项分别得到一个排列

Nor(array,m+1,n,S);

swap(array[i],array[m]);

}

if(m==n) //已完成排列

{

int sum=0; //sum用于记录该排列的价值

for(int i=0;i<n;i++) sum+=array[i]^(i+1);

(*S)|=sum; //将或和计入S

}

}

int main()

{

int n; //n为序列中元素个数

cin>>n;

int *a=new int[n];

int *ADD=new int(0);

for(int i=0;i<n;i++) cin>>a[i]; //输入序列

Nor(a,0,n,ADD);

cout<<*ADD<<endl;

delete []a;

delete []ADD;

return 0;

}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值