1.快速排序模板
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[(l+r)/2];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
int main()
{
int n,k;
scanf("%d%d", &n,&k);
for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
printf("%d\n", q[k-1]);
return 0;
}
2.归并排序模板
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+9;
int n;
int a[N],tmp[N];
void mergesort(int q[],int l,int r)
{
if(l>=r) return ;
int mid=l+r>>1;
mergesort(q,l,mid);
mergesort(q,mid+1,r);
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r)
if(q[i]<=q[j]) tmp[k++]=q[i++];
else tmp[k++]=q[j++];
while(i<=mid) tmp[k++]=q[i++];
while(j<=r) tmp[k++]=q[j++];
for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
mergesort(a,0,n-1);
for(int i=0;i<n;i++) cout<<a[i]<<" ";
return 0;
}
3.归并排序模板【逆序数对】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+9;
int n;
int a[N],tmp[N];
ll mergesort(int q[],int l,int r)
{
if(l>=r) return 0;
int mid=l+r>>1;
ll res=mergesort(q,l,mid)+mergesort(q,mid+1,r);
int i=l,j=mid+1,k=0;
while(i<=mid&&j<=r)
if(q[i]<=q[j]) tmp[k++]=q[i++];
else {tmp[k++]=q[j++];res+=mid-i+1;}
while(i<=mid) tmp[k++]=q[i++];
while(j<=r) tmp[k++]=q[j++];
for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
return res;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
printf("%lld\n",mergesort(a,0,n-1));
return 0;
}
4.整数二分【Mid分别在两个区间的不同模板】
用来查找某个整数是否在序列中存在,时间复杂度O( n 2 n^2 n2logn)
#include <bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,t,k;
int q[N];
int main()
{
scanf("%d%d",&n,&t);
for(int i=0;i<n;i++)
scanf("%d",&q[i]);
while(t--)
{
scanf("%d",&k);
int l=0,r=n-1;
while(l<r)
{
int mid=l+r>>1;
if(q[mid]>=k) r=mid;
else l=mid+1;
}
if(q[l]!=k) printf("-1 -1\n");//q[l]=q[r]
else
{
cout<<l<<" ";
int l=0,r=n-1;
while(l<r)
{
int mid=l+r+1>>1;
if(q[mid]<=k) l=mid;
else r=mid-1;
}
cout<<l<<endl;
}
}
return 0;
}
分巧克力
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100010;
int n,k;
int h[N],w[N];
int check(int mid)
{
ll res=0;
for(int i=0;i<n;i++)
res+=h[i]/mid*(w[i]/mid);
if(res>=k) return true;
return false;
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++) scanf("%d%d",&h[i],&w[i]);
int l=1,r=1e5;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",r);
return 0;
}
机器人跳跃问题
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100010;
int n,h[N];
bool check(int e)
{
for(int i=1;i<=n;i++)
{
e=2*e-h[i];
if(e>=1e5) return true;
if(e<0) return false;
}
return true;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
int l=0,r=1e5;
while(l<r)
{
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d\n",r);
return 0;
}
1221.四平方和
纯暴力枚举三次的O(
n
3
n^3
n3)代码会被卡掉,哈希算法在本题中是最坏情况,算法本身O(
N
2
N^2
N2),因此也会超时
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 2500010;
struct Sum
{
int s, c, d;
bool operator< (const Sum &t)const
{
if (s != t.s) return s < t.s;
if (c != t.c) return c < t.c;
return d < t.d;
}
}sum[N];
int n, m;
int main()
{
cin >> n;
for (int c = 0; c * c <= n; c ++ )
for (int d = c; c * c + d * d <= n; d ++ )
sum[m ++ ] = {c * c + d * d, c, d};
sort(sum, sum + m);
for (int a = 0; a * a <= n; a ++ )
for (int b = 0; a * a + b * b <= n; b ++ )
{
int t = n - a * a - b * b;
int l = 0, r = m - 1;
while (l < r)
{
int mid = l + r >> 1;
if (sum[mid].s >= t) r = mid;
else l = mid + 1;
}
if (sum[l].s == t)
{
printf("%d %d %d %d\n", a, b, sum[l].c, sum[l].d);
return 0;
}
}
return 0;
}
5.浮点数二分
#include <bits/stdc++.h>
using namespace std;
int main()
{
double n;
scanf("%lf",&n);
double l=-10000,r=10000;
while(r-l>1e-8)
{
double mid=(l+r)/2;
if(pow(mid,3)>=n) r=mid;
else l=mid;
}
printf("%lf\n",l);
return 0;
}
割绳子:绳子的根数一定定义成整数!
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
double a[N];
int n,m;
bool check(double mid)
{
int res=0;
for(int i=0;i<n;i++)
res+=a[i]/mid;
if(res>=m) return true;
return false;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++) scanf("%lf",&a[i]);
double l=0,r=1e9;
while(r-l>=1e-3)
{
double mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.2f\n",r);
return 0;
}