目录
第一章:蓄势待发,准备篇:
内容梳理:
1 : 给出三条边,问能否构成三角形:
首先算出三边的和,然后算出最大边的值,用三边和减去最大边的值就是其他两个边的长度,最用利用两边之和大于第三边来判断是否能够成三角形。
2:Ants poj1852
在一根长为L厘米的水平木棍上有n只蚂蚁,它们以每秒1cm/s的速度走到木棍一端就会掉下去。现在知道它们起始位置(相对于木棍左端点的距离)。但是不知道它们爬行的方向。两只蚂蚁相遇后,它们会掉头往反方向走。求所有蚂蚁都落下木棍的最短时间和最长时间。
注意是所有蚂蚁爬出的最大最小时间,不知道方向,如果用递归的话肯定会超时的,利用贪心的思想,只要求出每只蚂蚁爬出的最小时间,然后再比较找出最小时间的最大值就是所有蚂蚁爬出的最小时间。同理,最大时间就是求出每只蚂蚁爬出的最大时间,比较找出最大时间的最大值。
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int n;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
while(n--)
{
int l,m;
cin>>l>>m;
int min_number=0;
int max_number=0;
for(int i=0;i<m;++i)
{
scanf("%d",&a[i]);
min_number=max(min_number,min(a[i],l-a[i]));
max_number=max(max_number,max(a[i],l-a[i]));
}
printf("%d %d\n",min_number,max_number);
}
return 0;
}
3:抽签问题
1:O(n^4)
四层for循环:
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int n,m;
bool solve()
{
bool f=false;
for(int e=0; e<n; ++e)
for(int b=0; b<n; ++b)
for(int c=0; c<n; ++c)
for(int d=0; d<n; ++d)
if(a[e]+a[b]+a[c]+a[d]==m)
f=true;
return f;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
for(int i=0; i<n; ++i)
cin>>a[i];
if(solve())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
显然,在搜索第三层后,我们已经确定了使得条件成立的第四个数字是多少(m-a[e]-a[b]-a[c]),我们只需要判断这组数据里面是否有这个数就行了,这个时候我们用到了时间复杂度为O(logn)的算法-二分搜索。
2:O(n^3logn)
进行这个操作之前我们需要给原本的数据排个序,使得整个数据是按照从小到大的顺序排列的,然后直接调用STL里面的binary_searth()函数即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int n,m;
bool solve()
{
bool f=false;
for(int e=0; e<n; ++e)
for(int b=0; b<n; ++b)
for(int c=0; c<n; ++c)
if(binary_search(a,a+n,m-a[e]-a[b]-a[c]))
f=true;
return f;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
for(int i=0; i<n; ++i)
cin>>a[i];
sort(a,a+n);
if(solve())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
刚才我们是着眼于四层循环程序中最内层的循环。接下来,让我们着眼于内侧的两个循环,同刚才一样的思路,内侧的两个循环是在:检查是否有c和d使得kc+kd=m-ka-kb这种情况下并不能直接使用二分搜索,但是,如果预先枚举出kc+kd所得到n^2个数字并排好序,便可以利用二分搜索了。
3:O(n^2longn)
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e6+10;
int a[maxn];
int aa[maxn];
int n,m;
bool solve()
{
bool f=false;
for(int e=0; e<n; ++e)
for(int b=0; b<n; ++b)
if(binary_search(aa,aa+n*n,m-a[e]-a[b]))
f=true;
return f;
}
int main()
{
ios::sync_with_stdio(false);
while(cin>>n>>m)
{
for(int i=0; i<n; ++i)
cin>>a[i];
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
{
aa[i*n+j]=a[i]+a[j];
}
sort(aa,aa+n);
if(solve())
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}