P1631 序列合并

 


链接:P1631


在做这道题前,我们来考虑这样的一个问题

 

已知一个n*n的数表,保证在每一行上,有a[i][j]<a[i][j+1],我们怎样求出它的第k小的值?

对于这个问题,我们

 

在做这道题前,我们来考虑这样的一个问题

 

 

 

已知一个n*n的数表,保证在每一行上,有a[i][j]<a[i][j+1],我们怎样求出它的第k小的值?

 

对于这个问题,我们当然不能暴力搜索,看一下限制条件,我们可以很容易的知道第一小的值肯定在a[i][1]上,那么,我们只要考虑建立一个优先队列,然后把第一列的所有数字放进去即可。

那么第2,3,4~k小怎么办?我们先来考虑第二小。假如第一小是a[1][x],第二小可能在那?可能在第一列剩下的,也有可能是a[2][x],我们只要把a[2][x]放进队列即可。

其余同理。

看懂了这个,你就明白了这道题。 


这道题就是这个思想,但是具体实现还是会抽象一点,因为n太大了,必须要在用到[i][j]的时候再算然后加入队列。


 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[100010];
 7 int b[100010];
 8 int n;
 9 struct num{
10     int x;
11     int y;
12     int v;
13 };
14 
15 //因为不能直接开数组,所以我们要存一下坐标,用来计算下一个数 
16 bool operator<( num a, num b ){
17     return a.v>b.v;
18 }//重载 
19 
20 priority_queue <num> q;
21 int main(){
22     cin>>n;
23     for(int i=1;i<=n;++i)
24         cin>>a[i];
25     for(int i=1;i<=n;++i)
26         cin>>b[i];
27         sort(a+1,a+1+n);
28         sort(b+1,b+1+n);
29     for(int i=1;i<=n;++i)
30     {
31         num nu;
32         nu.v=a[1]+b[i];
33         nu.x=1;
34         nu.y=i;
35         q.push(nu);
36     }
37     int k=1;
38     while(k<=n){
39         num u;
40         u.x=q.top().x+1;
41         u.y=q.top().y;
42         u.v=(a[u.x]+b[u.y]);
43         printf("%d ",q.top().v);
44         q.pop();
45         q.push(u);
46         k++;
47     }
48     return 0;
49 }

AC

 

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇