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;
}
}