zoukankan      html  css  js  c++  java
  • POJ

    题目链接:

    https://cn.vjudge.net/problem/POJ-3476

    题目大意:

    一串长度为N的彩球,编号为1-N,每个球的颜色为R,G,B,给出它们的颜色,然后进行如下操作:

    每次消除连续颜色最长的最左端的一串,剩下的球如果分成两串,就把左右两串连接起来,输出每次消除的球的颜色及编号。

    解题思路:

    将球的同一颜色的串压入优先队列中,每次取出最长的串,相同长度的串取最左端的串。

    取出来之后,如果将小球分成了两串,如果两端颜色一样可以合并,那就网优先队列中压入新合成的串。每次取出串之后,将串的每一位进行标记,原因是由于没有将原来的两串删除就直接直接加入合并后的串,所以只需要标记一下已经取出,那么后加入的串由于长度长会先出优先队列。算法是正确的。

    对于需要输出具体是那些小球,利用pre数组和next数组,pre[i]表示第i个小球前面连着的小球的下标。next则表示后面连着的小球,用这两个数组模拟双端链表,可以输出具体是那些小球。

    用C++提交不会超时

     1 //#include<bits/stdc++.h>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 using namespace std;
     6 const int maxn = 1e6 + 10;
     7 typedef long long ll;
     8 struct node
     9 {
    10     char c;
    11     int pos, len;
    12     node(char c, int pos, int len):c(c), pos(pos), len(len){}
    13     bool operator <(const node& a)const
    14     {
    15         return len < a.len || len == a.len && pos > a.pos;//优先队列
    16     }
    17 };
    18 char s[maxn];
    19 int pre[maxn], next[maxn];
    20 bool vis[maxn];
    21 priority_queue<node>q;
    22 int main()
    23 {
    24     scanf("%s", s);
    25     int n = strlen(s);
    26     for(int i = 0; i < n;)
    27     {
    28         int st = i, len = 1;
    29         while(s[++i] == s[st])len++;
    30         //cout<<s[st]<<" "<<st<<" "<<len<<endl;
    31         q.push(node(s[st], st, len));
    32     }
    33     for(int i = 0; i < n; i++)
    34     {
    35         pre[i] = i - 1, next[i] = i + 1;
    36     }
    37     memset(vis, 0, sizeof(vis));
    38     while(!q.empty())
    39     {
    40         node now = q.top();
    41         q.pop();
    42         if(now.len <= 1)break;
    43         if(vis[now.pos])continue;
    44         printf("%c", now.c);
    45         int head = pre[now.pos], tail = now.pos;
    46         for(int i = 0; i < now.len; i++, tail = next[tail])
    47         {
    48             vis[tail] = 1;
    49             printf(" %d", tail + 1);
    50         }
    51         puts("");
    52         if(head >= 0)next[head] = tail;
    53         if(tail < n)pre[tail] = head;
    54         if(head < 0 || tail >= n || s[head] != s[tail])continue;
    55 
    56         int len = 2;
    57         while(pre[head] >= 0 && s[pre[head]] == s[head])
    58             head = pre[head], len++;
    59         while(next[tail] < n && s[next[tail]] == s[tail])
    60             tail = next[tail], len++;
    61         q.push(node(s[head], head, len));
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    大话设计模式Python实现-代理模式
    大话设计模式Python实现-装饰模式
    大话设计模式Python实现-策略模式
    设计模式Python实现-简单工厂模式
    Python文件读写机制
    python 多线程剖析
    I/O多路复用-EPOLL探索
    Python学习笔记:魔术方法详解
    Django学习笔记:为Model添加Action
    【Django】Django Debug Toolbar调试工具配置
  • 原文地址:https://www.cnblogs.com/fzl194/p/9336901.html
Copyright © 2011-2022 走看看