文章目录
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、二分不相似(与算法设计与分析66page 例3-2)
P1128
代码如下(示例):
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll len(ll k){
ll sum=1;
for(ll i=1;i<=k;i++) sum*=2;
return sum;
}
void solve(ll a,ll b,ll x,ll y,ll size){
if(size==1) return;
if(x-a<=size/2-1&&y-b<=size/2-1){
//左上角
cout<<a+size/2<<" "<<b+size/2<<" "<<1<<endl;
solve(a,b,x,y,size/2); //继续搜索左上角
solve(a,b+size/2,a+size/2-1,b+size/2,size/2); //右上角
solve(a+size/2,b,a+size/2,b+size/2-1,size/2); //左下角
solve(a+size/2,b+size/2,a+size/2,b+size/2,size/2); //右下角
}
else if(x-a<=size/2-1&&y-b>size/2-1){
//右上角
cout<<a+size/2<<" "<<b+size/2-1<<" "<<2<<endl;
solve(a,b,a+size/2-1,b+size/2-1,size/2); //左上角
solve(a,b+size/2,x,y,size/2); //继续搜索右上角
solve(a+size/2,b,a+size/2,b+size/2-1,size/2); //左下角
solve(a+size/2,b+size/2,a+size/2,b+size/2,size/2); //右下角
}
else if(x-a>size/2-1&&y-b<=size/2-1){
//左下角
cout<<a+size/2-1<<" "<<b+size/2<<" "<<3<<endl;
solve(a,b,a+size/2-1,b+size/2-1,size/2); //左上角
solve(a,b+size/2,a+size/2-1,b+size/2,size/2); //右上角
solve(a+size/2,b,x,y,size/2); //继续搜索左下角
solve(a+size/2,b+size/2,a+size/2,b+size/2,size/2); //右下角
}
else{
//右下角
cout<<a+size/2-1<<" "<<b+size/2-1<<" "<<4<<endl;
solve(a,b,a+size/2-1,b+size/2-1,size/2); //左上角
solve(a,b+size/2,a+size/2-1,b+size/2,size/2); //右上角
solve(a+size/2,b,a+size/2,b+size/2-1,size/2); //左下角
solve(a+size/2,b+size/2,x,y,size/2); //继续搜索右下角
}
}
int main()
{
int x,y,k,size;
cin>>k>>x>>y;
size=len(k);//方格大小
solve(1,1,x,y,size);
//左上角方格所在行,左上角方格所在列,公主所在的位置,方格大小
return 0;
}
二、二分不独立(同算法设计与分析70page 例3-3)
#include <bits/stdc++.h>//万能头
using namespace std;
int a[200050],n;
long long int max_sub_sum(int left,int right);//函数的声明
int main(){
cin>>n;//
for(int i=1;i<=n;i++){
//输入n个数据
cin>>a[i];
}
cout<<max_sub_sum(1,n);//求1到n之间的最大子段和
return 0;
}
long long int max_sub_sum(int left,int right){
long long int center,left_sub_sum,right_sub_sum,s1,s2,lefts,rights;
if(left==right){
//如果子段长度为1,返回子段大小
return a[left];
}
else{
center=(left+right)/2;//二分 分为左右两段
left_sub_sum=max_sub_sum(left,center);//递归求左边子段 将左边子段分的更小(分为左右两段)
right_sub_sum=max_sub_sum(center+1,right);//递归求右边子段 将右边子段分的更小(分为左右两段)
s1=-9999,lefts=0,s2=-9999,rights=0;//初始化子段的值,s1,s2的子段和要设为负数,因为子段中的数存在负数,最大字段和可能小于0
for(int i=center;i>=left;i--){
//求左边子段最大值
lefts+=a[i];
if(lefts>s1) s1=lefts;
}
for(int i=center+1;i<=right;i++){
//求右边子段最大值
rights+=a[i];
if(rights>s2) s2=rights;
}
if(s1+s2<=left_sub_sum&&left_sub_sum>=right_sub_sum) return left_sub_sum;//比较左子段和中间子段的和,返回最大值
if(s1+s2<=right_sub_sum&&left_sub_sum<=right_sub_sum) return right_sub_sum;
return s1+s2;
}
}
三、快排的几种写法
1.传统快排三个TLE
//传统快排三个TLE
#include <iostream>
using namespace std;
int n,a[1000001];
void qsort(int a[],int L,int R)
{
if(L>=R) return;
int left=L,right=R;
int pivot=a[left];
while(left<right)
{
while(left<right&&a[right]>=pivot) right--;
if(left<right) a[left]=a[right];
while(left<right&&a[left]<=pivot) left++;
if(left<right) a[right]=a[left];
if(left>=right) a[left]=pivot;
}
qsort(a,L,right-1);
qsort(a,right+1,R);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
qsort(a,1,n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}
2.使用随机数进行优化 快速排序 1个TLE
//随机数 快速排序 1个TLE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int n,a[1000001];
void Quicksort(int a[],int L,int R)
{
if(L>=R) return;
int left=L,right=R,temp,x=rand()%(R-L+1)+L;
temp=a[left];
a[left]=a[x];
a[x]=temp;
int pivot=a[left];
while(left<right)
{
while(left<right&&a[right]>=pivot) right--;
if(left<right) a[left]=a[right];
while(left<right&&a[left]<=pivot) left++;
if(left<right) a[right]=a[left];
if(left>=right) a[left]=pivot;
}
Quicksort(a,L,right-1);
Quicksort(a,right+1,R);
}
int main()
{
srand((int)time(NULL));
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
Quicksort(a,1,n);
for(int i=1;i<=n;i++) printf("%d ",a[i]);
return 0;
}
3.二分快速排序(yyds) 比sort()还快
//二分快速排序(yyds) AC
#include<iostream>
using namespace std;
int n,a[1000001];
void qsort(int L,int R)
{
int mid=a[(L+R)/2],temp;
int left=L,right=R;
do
{
while(a[left]<mid) left++;
while(a[right]>mid) right--;
if(left<=right)
{
temp=a[left];
a[left]=a[right];
a[right]=temp;
left++;
right--;
}
}while(left<=right) ;
if(L<right) qsort(L,right);
if(R>left) qsort(left,R);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
qsort(1,n);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
}
4.C++ STL大法
//C++ STL大法
#include <iostream>
#include <algorithm>
using namespace std;
int a[1000010],n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}