P1007 独木桥
这题其实思路通了就没啥问题,主要就是可以把两个士兵相遇看作两个士兵互换了方向,或者说两个士兵擦肩而过,max好求:
maxx=max(maxx,a[i]);
maxx=max(maxx,l+1-a[i]);
min即是在保证全员通过独木桥的情况下的最少时间:
minn=max(min(a[i],l+1-a[i]),minn);
完整代码如下::
#include<bits/stdc++.h>
using namespace std;
const int N=5005;
int main()
{
int l,n;
cin>>l>>n;
int a[N];
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
int maxx=0;
int minn=0;
for(int i=1;i<=n;i++)
{
maxx=max(maxx,a[i]);
maxx=max(maxx,l+1-a[i]);
minn=max(min(a[i],l+1-a[i]),minn);
}
cout<<minn<<" "<<maxx;
return 0;
}
P1223 排队接水
根据猜想出来的等待时长的计算结果:
可知开始等待时长越小,最后和越小,故对所有接水时长进行排序,从小到大依次接水
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
long long a[N],b[N];
int main()
{
int n;
cin>>n;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(b[i]==a[j])
{
a[j]=-1;
cout<<j<<" ";
break;
}
}
cout<<endl;
long long num=0,ans=0;
for(int i=1;i<n;i++)
{
num+=b[i];
ans+=num;
}
cout<<fixed<<setprecision(2)<<double(ans)/n;
return 0;
}
这个代码需要对每个时长所在序号进行查找,用结构体改进代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct p
{
int num;
long long wait;
}a[N];
bool cmp(p a1,p a2)
{
return a1.wait<a2.wait;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
a[i].num=i;
cin>>a[i].wait;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
cout<<a[i].num<<" ";
cout<<endl;
double ans=0,nu=0;
for(int i=1;i<n;i++)
{
nu+=a[i].wait;
ans+=nu;
}
cout<<fixed<<setprecision(2)<<ans/n;
return 0;
}
P1803 凌乱的yyy/线段覆盖
该题相当于从一根绳子上截取给定begin和end长度,统计绳子能截多少次
根据贪心思想,每次应取end最小的一段,这样留给后面绳子截取的数量更多,能取到最大数目
(可以通过反证法证明:至少存在一个最长时间序列,其中包含最小结束事件)
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct p
{
int begin,end;
}contest[N];
bool cmp(p a1,p a2)
{
return a1.end<a2.end;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>contest[i].begin>>contest[i].end;
sort(contest+1,contest+1+n,cmp);
int ans=0,k=0;
for(int i=1;i<=n;i++)
{
if(k<=contest[i].begin)
{
k=contest[i].end;
ans++;
}
}
cout<<ans;
return 0;
}
P1031 均分纸牌
这题需要明确几点:
1、纸牌最终数量相同且是可求的;
2、最终一定可以使纸牌数目相同;
3、相邻两堆纸牌互相转移,若从a堆移到b堆而使a堆纸牌直接达到目标数量的移动次数最少
故有以下代码:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
int ans=0;
int main()
{
int n;
int a[N];
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ans+=a[i];
}
int x=ans/n;
int k=0;
for(int i=1;i<=n;i++)
a[i]-=x;
for(int i=n;i>=1;i--)
{
if(a[i]==0)
continue;
a[i-1]=a[i]+a[i-1];
k++;
}
cout<<k;
return 0;
}