hdu 4544 湫湫系列故事——消灭兔子

来源:互联网 发布:文本压缩算法 编辑:程序博客网 时间:2024/05/21 19:37

原题: http://acm.hdu.edu.cn/showproblem.php?pid=4544

//hdu 4544//思路:为每一只兔子找能够杀死自己并且花费Q币最少的箭,关键在于不要超时,详细过程: //     每一只兔子按血量从大到小排序,每一把箭按攻击值从大到小排序。接下来for循环,为每一只兔子找箭,//     遍历每一只兔子,查找攻击值大于兔子血量的箭,把这些箭的Q币压入优先队列//     能够杀死上一只兔子的箭一定能杀死下一只兔子,因为兔子的血量是从大到小排列的,把箭都压进队列后,//     每次取优先队列的头(即Q币最小)的箭即可,但如果队列为空,表示没有一把剑能杀死当前的兔子,则跳出循环,输出No,有则继续遍历,直到遍历完所有的兔子。 //优先队列可以,multiset也可以,使用队列要注意自己重写一个cmp,用greater<int>会报编译错误。//数据可能达到100亿,用long long #include<iostream>#include<cstdio>#include<queue>#include<algorithm> using namespace std;typedef long long ll; int rab[100001];struct J{int di;int pi;}j[100001];int cmp1(int a,int b)//按血量从大到小排序 {return a>b;}int cmp2(J a,J b)//按伤害值由大到小排序 {return a.di>b.di;}struct cmp   //队列要用到的cmp结构体 {bool operator ()(int a,int b){return a>b;}};int main(){int n,m;while(~scanf("%d %d",&n,&m)){for(int i=0;i<n;i++){scanf("%d",&rab[i]);//兔子 }for(int i=0;i<m;i++)//箭 {scanf("%d",&j[i].di);}for(int i=0;i<m;i++){scanf("%d",&j[i].pi);}if(n>m){//兔子数目大于箭的数目,不能杀死全部兔子 printf("No\n");continue;} sort(rab,rab+n,cmp1); //排好序 sort(j,j+m,cmp2);priority_queue<int,vector<int>,cmp>q1;//存放q币优先队列,由小到大 int k=0; //箭的下标 ll money=0;int flag=1;//是否能够消灭全部兔子,flag=1能,flag=0不能 for(int i=0;i<n;i++)//遍历每一只兔子 {int di=rab[i];//当前兔子的血量 for(;k<m;k++){if(j[k].di>=di)//找那些可以杀死兔子的,把q币压入队列 {q1.push(j[k].pi);}else{break;}}if(q1.size()==0){//如果没有一支箭可以杀死这只兔子,flag=0,提前结束循环 flag=0;break;}else{money=money+q1.top();q1.pop();}} if(flag){ //可以杀死全部兔子 printf("%lld\n",money);}else{  //不能杀死全部兔子 printf("No\n");}} return 0;}   //AC
有一道类似的题可以巩固加深 : http://acm.hdu.edu.cn/showproblem.php?pid=4864

原创粉丝点击