1. 程式人生 > >貪心+優先佇列之更改優先順序-hdu1896

貪心+優先佇列之更改優先順序-hdu1896

題目描述:

題目理解:

  Sempr從位置0往前走,一路上他會遇到石子,如果這顆石子是他遇到的第奇數顆石子,那麼他就把石子往前扔出去,如果他遇到的是第偶數顆石子,他會把它留在原地。需要注意的是,Sempr前面扔出去的石子,會繼續作為後續會遇到的石子。如果在一個位置上有多顆石子,那麼選出扔的最遠的那顆石子扔出去。

  比如說第一個測試案例:Sempr在位置1遇到了第一顆石子,他將石子扔到了1+5=6的位置上。Sempr繼續往前走,在位置2上遇到第二顆石子,他將其留在原地,並且繼續往前走。當Sempr走到位置6時,他遇到了第三顆石子(這顆石子是由位置1的第一顆石子扔到這兒的),他將這顆石子扔到了6+5=11的位置上,並繼續往前走。當Sempr走到位置11時,他遇到第四顆石子,他將其留在原地。至此,該測試案例中的石子就扔完了。所以最終的結果為11。

這道題由於運用到了優先佇列,並且在同一個位置有多顆石子時需要更改佇列的優先順序,所以自己去了解了一下關於優先順序修改的相關操作。

C/C++對bool operator < (const p &a)const的認識:http://www.cnblogs.com/ECJTUACM-873284962/p/6771262.html

結構體內嵌比較函式:http://www.cnblogs.com/ZERO-/p/9347296.html

程式碼分析:

#include <iostream>
#include <queue>
#include <cstdio>
using
namespace std; struct stone { int d; int w; bool operator <(const stone &a)const//operator為C++裡面的過載函式;括號中的const表示引數a物件不會被修改,最後的const表明呼叫函式物件不會被修改! { if(a.d==d)//如果石子的位置與佇列中其他石子的位置一樣 return a.w<w;//在優先佇列中,排序方式與sort函式相反,即預設的排序方式是a.w>w,當前物件的w如果大於其他元素的w(即a.w),那麼w的優先順序更高
return a.d<d;//否則,位置靠前的優先順序高 } }z; int main() { int t; scanf("%d",&t); while(t--) { priority_queue<stone>q; int n; scanf("%d",&n); while(n--) { scanf("%d %d",&z.d,&z.w); q.push(z); } int i=1; while(i) { if(i%2==1)//如果遇到的石頭為第奇數顆,扔出去,並將該石子存入佇列 { z=q.top(); q.pop(); z.d+=z.w; q.push(z); if(q.size()==1)//如果佇列中只還剩下1個元素,取出來後退出。 { printf("%d\n",q.top().d); break; } } else//如果遇到的石頭為第偶數顆,不理它 { q.pop(); } i++; } } return 0; }