#include
/**
*分治法
*快速排序
**/
using namespace std;
//交换函数
void swap(int*a,int*b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
//快速排序函数 选取任意一个数,使得左边的数都小于这个数,右边的数都大于这个数
//继续重复上述操作,直到递归全部完成
void QucikSort(int*element,int left,int right)
{
//递归终结条件 ,当左边大于等于右边时退出函数
if(left>=right)
return;
//i赋值为第一个数
int i=left;
//j赋值为最后一个数
int j=right;
//k任意取一个数(一般为第一个)
int k=element[i];
while(i<j)
{
if(j>i&&element[j]>=k) //如果date[j]大于k j--
j--;
swap(element[i],element[j]);//if不满足后执行交换
if(i<j&&element[i]<=k) //如果 date[i]小于k i++
i++;
swap(element[i],element[j]);//if不满足执行交换
}
QucikSort(element,left,i-1);//左边继续执行相同操作
QucikSort(element,i+1,right);//右边继续执行相同操作
}
void Output(int*element,int length)
{
for(int i=0;i<length;i++)
cout<<element[i]<<",";
}
int main(int argc, char** argv) {
//测试
int a[]={1,2,3,9,5,6,0};
QucikSort(a,0,6);
//输出
Output(a,7);
return 0;
}
#include
/**
*分治法
*归并排序排序
**/
using namespace std;
//合并左右两半为一个新的有序数组,并拷贝到原数组
void Merge(int*element,int left,int m,int right,int*newelement)
{
int L=left;
int R=m+1;
int pos=0;
//合并左右两半有序数组依次放入新数组
while(L<=m&&R<=right)
{
if(element[L]<element[R])
newdate[pos++]=element[L++];
else
newdate[pos++]=element[R++];
}
//防止左边或者右边多出的数未加入到新数组
while(L<=m)
newelement[pos++]=element[L++];
while(R<=right)
newelement[pos++]=element[R++];
//拷贝回原数组
for(int i=0;i<right-left+1;i++)
element[left+i]=newelement[i];
}
//归并排序函数
//思路: 1.把前一半排序 2.把后一半排序 3.把前后两半归并到一个新有序数组,然后拷贝回原数组
void MergeSort(int*element,int left,int right,int*newelement)
{
//变量m存放数组长度的中间值
int m;
//递归终止条件
if(left>=right)
return;
//通过此计算方式代替(right+left)/2获取中间值 (此计算方式更安全)
m=left+(right-left)/2;
//左右递归
MergeSort(element,left,m,newelement);
MergeSort(element,m+1,right,newelement);
//并
Merge(element,left,m,right,newelement);
}
void Output(int*element,int length)
{
for(int i=0;i<length;i++)
cout<<element[i]<<",";
}
int main(int argc, char** argv) {
//测试
int a[]={1,2,3,9,5,6,0};
int*b=new int[sizeof(a)/4];
MergeSort(a,0,6,b);
//输出
Output(a,7);
return 0;
}
#include
#include
/**
*分治法
*最大值和次大值
**/
using namespace std;
void Solve(int*date,int& max1,int& max2,int low,int height)
{
//只有一个数的情况 最大值为这个数,次大值为负无穷
if(low==height)
{
max1=date[low];
max2="负无穷";
}
//两个数的情况 最大值为两个数中最大的一个,次大值为两个数中最小的一个
else if(height-low==1)
{
max1=max(date[low],date[height]);//最大值
max2=min(date[low],date[height]);//次大值
}
//两个数以上的情况 分为左边右边递归重复上述代码
else
{
int mid=low+(height-low)/2;
int lmax1,lmax2;
Solve(date,lmax1,lmax2,low,mid); //求左边的最大值和次大值
int hmax1,hmax2;
Solve(date,hmax1,hmax2,mid+1,height); //右边的最大值和次大值
if(lmax1>hmax1)
{
max1=lmax1; //最大值赋值为lmax1
max2=max(lmax2,hmax1); //次大值在lmax2和hmax1里面求得最大值
}
else
{
max1=hmax1;//最大值赋值为hmax1
max2=max(hmax2,lmax1);//次大值在hmax,lmax1里面求得最大值
}
}
}
void Output(int& max1,int& max2)
{
cout<<"最大值:"<<max1<<"次大值:"<<max2;
}
int main(int argc, char** argv) {
//测试
int a[]={1,2,3,9,5,6,0};
int max1,max2;
Solve(a,max1,max2,0,6);
//输出
Output(max1,max2);
return 0;
}
#include
/**
*分治法
*折半查找
**/
using namespace std;
int BinSearch(int*date,int left,int right,int D)
{
int mid;
//若超出范围则返回-1 表示未找到
if(left>=right)
return -1;
//求中间值 代替(left+right)/2方式 防止溢出
mid=left+(right-left)/2;
//目标值大于中间值 则说明左边整体小于目标值 此时left移到mid+1
if(D>date[mid])
BinSearch(date,mid+1,right,D);
// 目标值小于中间值 则说明右边整体大于目标值 此时right移到mid-1
else if(D<date[mid])
BinSearch(date,left,mid-1,D);
//若找到返回目标值所在位置
else
return mid;
}
int main(int argc, char** argv) {
//测试
int a[]={1,2,3,4,5,6,7};
int lo=BinSearch(a,0,6,4);
//输出
cout<<lo; //位置为3
return 0;
}
2019 年女排世界杯,一共 12 个队伍进行比赛,比赛形式是:单循环赛制。也就是每个队伍之间进行有且仅有一场比赛,编写程序,输入 k 个队伍,输出对应的对阵表
例如 k 等于 4,表示 4 个队伍。单循环赛的赛程如下。
队伍 | 第一天对手 | 第二天对手 | 第三天对手 |
1 | 2 | 3 | 4 |
2 | 1 | 4 | 3 |
3 | 4 | 1 | 2 |
4 | 3 | 2 | 1 |