洛谷P1007 独木桥
思路:
这题需要知道的一点就是当两个士兵相遇时,其实没有任何影响;因为彼此都是士兵,没有任何不同,相当于互相穿过了对方。知道了士兵相遇之后并不对结果产生影响之后,通过枚举每一个点,知道当前点的士兵(们)到达两边的最短时间和最长时间,然后找出能完成逃跑的最小与最大时间即可。
代码:
#include <iostream>
using namespace std;
const int N=5e3+10;
int l,n,a[N];
int main()
{
cin>>l>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
a[x]++;
}
int minl=0,maxl=0;
for(int i=1;i<=l;i++)
{
if(a[i]==0)continue;
int lt,ht;
lt=a[i]+min(i-0,l+1-i)-1;
minl=max(lt,minl);
ht=a[i]+max(i-0,l+1-i)-1;
maxl=max(ht,maxl);
}
cout<<minl<<' '<<maxl;
return 0;
}
洛谷P1223 排队接水
思路:
自然很容易知道接水时间短的应该最先接水,这样总的接水时间就会最短,等待的时间也会最短,所以对所有人的接水时间进行一个排序(同时用结构体存一下他们的原本的坐标),最后将他们总的接水时间加在一起(除去最后一个,因为没人需要等他)除以人数即可得到答案。
代码:
#include <algorithm>
#include <iostream>
using namespace std;
const int N=1e6+10;
int n;
struct T
{
int t,id;
bool operator < (const T &w)const
{
return t<w.t;
}
}t[N];
int main()
{
cin>>n;
double res=0;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
t[i]={x,i};
}
sort(t+1,t+n+1);
for(int i=1;i<=n;i++)
{
if(i!=n)res+=t[i].t*(n-i);
printf("%d ",t[i].id);
}
puts("");
printf("%.2lf",res/n);
return 0;
}
洛谷P1803 凌乱的yyy / 线段覆盖
思路:
给定一些区间,求最大不重合区间数,算是模板题吧。
对所有给定区间的右端点进行排序,然后通过比较下个区间的左端点和当前区间的右端点,即可判断(记得时时更新当前区间的右端点)。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e6+10;
struct Edge
{
int l,r;
bool operator < (const Edge &w)const
{
return r<w.r;
}
}edge[N];
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
int left,right;
cin>>left>>right;
edge[i]={left,right};
}
sort(edge,edge+n);
int res=0;
int ed=-1;
for(int i=0;i<n;i++)
{
if(edge[i].l>=ed)
{
res++;
ed=edge[i].r;
}
}
cout<<res;
return 0;
}
洛谷P1031 [NOIP2002 提高组] 均分纸牌
思路:
从第一堆开始,每次当前堆与平均数作比较,少了就从后面那一堆拿点过来,多了就给点给后面的。(因为只能和邻堆之间进行操作)
代码:
#include <iostream>
using namespace std;
const int N=110;
int a[N];
int main()
{
int n,sum=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
sum=sum/n;
int res=0;
for(int i=0;i<n-1;i++)
{
int mid=sum-a[i];
if(mid!=0)
{
res++;
a[i+1]-=mid;
}
}
cout<<res;
return 0;
}