zoukankan      html  css  js  c++  java
  • 集合删数 (vijos 1545) 题解

    【问题描述】

        一个集合有如下元素:1是集合元素;若P是集合的元素,则2 * P +1,4*P+5也是集合的元素,取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M个数位上的数字,使得剩下的数字最大,编程输出删除前和删除后的多位数字。

    注:不存在所有数被删除的情况。

    【样例输入】     

        5 4

    【样例输出】

        137915

        95

    【解题思路】

         首先,我们可以将该问题转化为两个子问题:

         1:求2*p+1与4*p+5两个集合中前k个数组成的数。

         2:求如何删去m个数字使留下的数最大,并输出该数。

        对于子问题1,其实是很好办的,直接将两个集合转化为两个队列,取走两个队列中更小的队首元素,并将其扩展放入到两个集合中,直到取出了k个数。

        那么关键在于如何解决子问题2。

        既然要使留下的数最大,那么自然是越高位越大越好,于是,对于某一个数字是取还是舍,我们应遵循下面两个原则:

        1:如果该数字比其之前的数字大,那么我们应尽量舍去之前的数字。

        2:如果舍去的数字已经有m个了,那就不必舍去了。

        因此,对于每一个数字,我们应把它与它前面的数字进行比较,如果满足上述两个原则,那么就取代其之前的数。详见代码。

    【代码实现】

    var t,k:array[1..200000] of longint;
        sta:array[0..200000] of char;
        t1,t2,i,n,m,l,top,r1,r2:longint;
        s,st:ansistring;
    begin
     readln(n,m);
     i:=1;
     t[1]:=3;
     k[1]:=9;
     t1:=1;
     t2:=1;
     r1:=1;
     r2:=1;
     s:='1';
     while i<n do
      if t[r1]<k[r2] then
       begin
        inc(i);
        str(t[r1],st);
        s:=s+st;
        inc(t1);
        t[t1]:=2*t[r1]+1;
        inc(t2);
        k[t2]:=4*t[r1]+5;
        inc(r1);
       end
      else
       begin
        inc(i);
        str(k[r2],st);
        s:=s+st;
        inc(t1);
        t[t1]:=2*k[r2]+1;
        inc(t2);
        k[t2]:=4*k[r2]+5;
        inc(r2);
       end;
     writeln(s);//解决子问题1
     l:=length(s);
     m:=l-m;
     sta[0]:=chr(57);
     top:=1;
     for i:=1 to l do
      begin
       while(s[i]>sta[top-1])and(top+l-i>m)do//满足两个原则,取代
        dec(top);
       sta[top]:=s[i];
       inc(top);
      end;
     for i:=1 to top-1 do
      if sta[i]<>'0' then
       break;//注意:前导0不要输出
     for i:=i to m do
      write(sta[i]);
     writeln;
    end.
  • 相关阅读:
    nodejs内存溢出解决方法
    mongodb副本集与分片结合
    node加密
    守护进程,互斥锁,IPC,队列,生产者与消费者模型
    并发编程
    粘包问题
    socket编程
    xml模块
    网络编程
    异常处理
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4501416.html
Copyright © 2011-2022 走看看