Crossing River POJ-1700
- 题意:n个人过河,一个船能容纳两个人,每个人的过河速度不同,一个船的过河速度由最慢的那个人决定,求最慢的过河速度
- 题解:
分类讨论:n=1 dis=a[1]
n=2 dis=a[2]
n=3 dis=a[1]+a[2]+a[3]
n>=4 想把速度最大的两个人过河
两种方案:
dis=a[1]+a[1]+a[3]+a[4]
dis=a[1]+a[2]+a[2]+a[4]
取其中最小的那个然后递归 - 代码:
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1e3+10;
int t;
int n;
int a[N];
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+1+n);
int ans=0;
while(n)
{
if(n==1)
{
ans+=a[1];
n--;
}
else if(n==2)
{
ans+=a[2];
n-=2;
}
else if(n==3)
{
ans+=a[1]+a[2]+a[3];
n-=3;
}
else if(n>=4)
{
int dis1=a[n]+a[n-1]+a[1]+a[1];
int dis2=a[n]+a[1]+a[2]+a[2];
n-=2;
ans+=min(dis1,dis2);
}
}
cout<<ans<<endl;
}
}
Radar Installation POJ-1328
- 题意:
n个坐标系上的点,现在要在x轴上建雷达站把它们都包起来,雷达的探测半径是d,求最小的雷达数(若无解决方案,输出-1) - 题解:每个点的被覆盖范围如图,然后就找最少多少个点能将这些区间覆盖就好,按区间的左端点排序,然后从左到右遍历,规划雷达方案即可
- 代码:
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=1100;
int n,d;
struct point
{
double x,y;
bool operator <(const point &p)
{
return x<p.x;
}
}a[N];
int main()
{
int cnt=0;
while(cin>>n>>d)
{
cnt++;
if(n==0&&d==0)break;
int flag=0;
double ans=-1;
for(int i=1;i<=n;i++)
{
double x,y;
cin>>x>>y;
if(y>d)flag=1;
else {
a[i].x=x-sqrt(d*d-y*y);
a[i].y=x+sqrt(d*d-y*y);
}
}
cout<<"Case "<<cnt<<": ";
if(flag==1)
{
cout<<ans<<endl;
continue;
}
sort(a+1,a+1+n);
double l=a[1].x,r=a[1].y;
ans=1;
for(int i=2;i<=n;i++)
{
if(a[i].x>=l&&a[i].y<=r)
{
l=a[i].x;
r=a[i].y;
}
else if(a[i].x<=r&&a[i].y>=r)
{
l=a[i].x;
}
else if(a[i].x>r)
{
l=a[i].x;
r=a[i].y;
ans++;
}
}
cout<<ans<<endl;
}
}
Doing Homework again HDU-1789
- 题意:
t组测试样例,每组样例有n组数据,应该完成作业的天数和迟交被扣的分,现求期末被扣最少的分数解 - 题解:
按照分数进行排序,然后从大到小进行遍历,优先填充与对应天数相等的位置,若该位置已满,则向前查看,若前面的天数都满,则说明该作业只能迟交扣分 - 代码:
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1100;
int t;
int n;
struct node
{
int score;
int day;
bool operator<(const node &p)const
{
return score>p.score;
}
}a[N];
int flag[N];
int main()
{
cin>>t;
while(t--)
{
memset(flag,0,sizeof flag);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].day;
}
for(int i=1;i<=n;i++)
{
cin>>a[i].score;
}
sort(a+1,a+1+n);
int ans=0;
for(int i=1;i<=n;i++)
{
int j=0;
while((a[i].day-j)>0&&flag[a[i].day-j]==1)
{
j++;
}
if((a[i].day-j)==0)ans+=a[i].score;
else if((a[i].day-j)>0)
{
flag[a[i].day-j]=1;
}
}
cout<<ans<<endl;
}
}
湫湫系列故事——消灭兔子 HDU-4544
- 题意:
多组测试数据,n个兔子,m支箭
n个兔子有bi血,每支箭让兔子掉di血,花费pi个qq币
求把兔子都杀死花费的最少qq币,若无方案,输出No
注:每支箭只能用一次,每个兔子只能被射一次 - 题解:
兔子血量从大到小排序,箭开struct按照di排序
然后对兔子血量进行遍历,将所有能杀死该兔子的箭放到优先队列离去(因为已经排序了,所以不用考虑出队列的问题),然后将队头加到答案里去(若队列无元素,则直接flag=0)
注:
最后答案要用long long存不然会炸
同时在队列存值的时候只要存pi就好(最初还在想存进节点还要提出来判断……后来发现有点蠢) - 代码:
#include <iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define ll long long
using namespace std;
const int N=1e5+10;
int n,m;
struct node
{
int d,p;
bool operator< (const node &q)const
{
return d>q.d;
}
}a[N];
int b[N];
int main()
{
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=m;i++)
{
cin>>a[i].d;
}
for(int i=1;i<=m;i++)
{
cin>>a[i].p;
}
sort(a+1,a+1+m);
sort(b+1,b+1+n);
reverse(b+1,b+1+n);
priority_queue<int, vector<int> , greater<int> >q;
int j=1;
int flag=0;
ll ans=0;
for(int i=1;i<=n;i++)
{
while(a[j].d>=b[i]&&j<=m)
{
q.push(a[j].p);
j++;
}
if(q.size()==0)
{
flag=1;
break;
}
else
{
ans+=q.top();
q.pop();
}
}
if(flag==1)
{
cout<<"No"<<endl;
}
else cout<<ans<<endl;
}
}