poj3476 A Game with Colored Balls (优先队列,链表)

该博客探讨了一种策略,即每次选取最长的左侧颜色球段,并利用优先队列来实现这一过程。同时,文章指出在删除球段时可以采用链表结构,其中数组模拟链表能带来更优的效率。值得注意的是,博主发现用g++编译代码会导致超时(可能由于代码中存在缺陷),而改用c++编译则能成功通过评测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每次取最长的最左边一段,可以使用优先队列来实现。而对于每次删除一段则可以使用链表来实现,事实上这里使用数组来模拟链表会有更好的效果。而且最后的评测使用g++会TLE(应该是我代码残了),使用c++可以过。

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;

struct Node
{
	char c;
	int pos, len;
	Node(char c, int a, int b)
	{
		this->c = c; pos = a; len = b;
	}
};

bool operator<(const Node& a, const Node& b)
{
	if (a.len == b.len) return a.pos > b.pos;
	else return a.len < b.len;
}

const int MAXN = 1000005;
char s[MAXN];
int pre[MAXN], next[MAXN];
bool vis[MAXN];
priority_queue<Node> q;

int main()
{
	scanf("%s", s);
	int pos = 0, n = strlen(s);
	while (s[pos] != '\0')
	{
		int st = pos, len = 1;
		while (s[++pos] == s[st]) len++;
		q.push(Node(s[st], st, len));
	}
	for (int i = 0; s[i] != '\0'; i++) 
	{
		pre[i] = i - 1;
		next[i] = i + 1;
	}
	memset(vis, false, sizeof(vis));
	
	while (!q.empty())
	{
		Node pnt = q.top(); q.pop();
		if (pnt.len <= 1) break;
		if (vis[pnt.pos]) continue;
		printf("%c", pnt.c);
		int front = pre[pnt.pos], back = pnt.pos;
		for (int i = 0; i < pnt.len; i++, back = next[back])
		{
			vis[back] = true;
			printf(" %d", back + 1);
		}
		printf("\n");
		
		if (front >= 0) next[front] = back;
		if (back < n) pre[back] = front;
		if (front < 0 || back >= n || s[front] != s[back]) continue;
		int len = 2;
		while (pre[front] >= 0 && s[pre[front]] == s[front])
		{
			front = pre[front];
			len++;
		}
		while (next[back] < n && s[back] == s[next[back]])
		{
			back = next[back];
			len++;
		}
		q.push(Node(s[front], front, len));
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值