P1920 合并果子 求助
  • 板块学术版
  • 楼主fzy1026
  • 当前回复7
  • 已保存回复7
  • 发布时间2022/3/14 18:31
  • 上次更新2023/10/28 06:35:54
查看原帖
P1920 合并果子 求助
421805
fzy1026楼主2022/3/14 18:31

https://www.luogu.com.cn/problem/P1090
这道题我之前写过一遍过了

后来心血来潮想用块状链表重写

然后就听取WA声一片了

调了半天也没弄明白

这是原来的码:

#include <bits/stdc++.h>
#include <conio.h>
#include <stdlib.h>
#include <unistd.h>

#define N 1000
#define M 50
using namespace std;

bool Debug = 0;

struct NODE
{
	long long data[M];
	long long next;
	long long m;
	void init()
	{
		for (long long i = 0; i < M; i++)
		{
			data[i] = 0;
		}
		next = 0;
		m = 0;
	}

	long long Max()
	{
		return data[m - 1];
	}

	long long Min()
	{
		return data[0];
	}

	void del(long long d)
	{
		if(Debug)
			cout<<"pool del:"<<d<<endl;
		for (long long i = d; i < m - 1; i++)
		{
			data[i] = data[i + 1];
		}
		m--;
	}

	void push(long long d)
	{
		if(Debug)
			cout<<"pool push:"<<d<<endl;
		if (m == 0)
		{
			if(Debug)
				cout<<"empty push:"<<endl;
			data[m] = d;
		}
		else if (d <= Min())
		{
			if(Debug)
				cout<<"head push:"<<endl;
			for (long long i = m; i > 0; i--)
			{
				data[i] = data[i - 1];
			}
			data[0] = d;
		}
		else if (d >= Max())
		{
			if(Debug)
				cout<<"tali push"<<endl;
			data[m] = d;
		}
		else
		{
			if(Debug)
				cout<<"Start searching:\n";
			long long l = 0, r = m - 1;
			long long mid;
			while (l <= r)
			{
				mid = (l + r) / 2;
				if(Debug)
				{
					cout<<"mid="<<mid<<endl;
					cout<<"l="<<l<<endl;
					cout<<"r="<<r<<endl;
					cout<<"\n";
				}
				if (data[mid - 1] <= d && d <= data[mid])
				{
					break;
				}
				else if (data[mid - 1] > d)
				{
					r = mid - 1;
				}
				else
				{
					l = mid + 1;
				}
			}
			if(Debug)
				cout<<"final mid = "<<mid<<endl;
			for (long long i = m; i > mid; i--)
			{
				data[i] = data[i - 1];
			}
			data[mid] = d;
		}

		m++;
	}
};

struct LINK
{
	NODE pool[N];
	long long ph;
	long long head;


	void init()
	{
		for (long long i = 0; i < N; i++)
		{
			pool[i].init();
		}
		ph = 1;
		head = 0;
	}

	void add(long long d)
	{
		if(Debug)
		{
			cout<<"add:"<<d<<endl;
		}
		long long p = pool[d].next;
		if (p == 0)
		{
			return ;
		}
		for (long long i = 0; i < pool[p].m; i++)
		{
			pool[d].data[i + pool[d].m] = pool[p].data[i];
		}
		pool[d].m += pool[p].m;
		pool[d].next = pool[p].next;
		pool[p].init();
		pool[p].next = ph;
		ph = p;
	}

	void del(long long d1, long long d2)
	{
		if(Debug)
			cout<<"del:"<<d1<<","<<d2<<endl;

		pool[d1].del(d2);
		long long p = pool[d1].next;
		if (pool[d1].m + pool[p].m < M)
		{
			add(d1);
		}
	}

	long long nextp()
	{
		long long p = ph;
		if (pool[ph].next)
		{
			ph = pool[ph].next;
		}
		else
		{
			ph++;
		}
		return p;
	}

	void slime(long long d)
	{
		if(Debug)
			cout<<"slime:"<<d<<endl;
		long long p = nextp();
		long long mid = M / 2;
		for (long long i = mid; i < M; i++)
		{
			pool[p].data[i - mid] = pool[d].data[i];
			pool[d].m--;
			pool[p].m++;
		}
		pool[p].next = pool[d].next;
		pool[d].next = p;
	}

	void push(long long d)
	{
		if(Debug)
			cout<<"Push:"<<d<<endl;
		if (head == 0)
		{
			head = nextp();
			pool[head].push(d);
		}
		else
		{
			long long i;
			for (i = head; i != 0; i = pool[i].next)
			{
				if (pool[i].Max() >= d)
				{
					if(Debug)
						cout<<"Push in "<<i<<endl;
					pool[i].push(d);
					break;
				}
				if (pool[i].next == 0)
				{
					if(Debug)
						cout<<"Push in "<<i<<endl;
					pool[i].push(d);
					break;
				}
			}

			if (pool[i].m >= M)
			{
				slime(i);
			}
		}
	}

	void debug()
	{
		cout << "————————————" << endl;
		for (long long i = head; i != 0; i = pool[i].next)
		{
			cout << "  pool " << i << ":";
			
			for (long long j = 0; j < pool[i].m; j++)
			{
				cout << pool[i].data[j] << " ";
			}
			
			cout << "  m:" << pool[i].m << endl;
		}
		cout << "  ph:" << ph << endl;
		cout << "  head:" << head << endl;
		cout << "————————————" <<"\n\n";
	}
};

int main()
{
	//freopen("P1090_2.in","r",stdin);
	LINK a;
	a.init();
	long long n;
	cin >> n;
	for (long long i = 1; i <= n; i++)
	{
		long long e;
		cin>>e;
		a.push(e);
		//if(i >= 818)
//		{
//			cout<<"\ni : "<<i<<"   e="<<e<<endl;
//			a.debug();
//			Debug = 1;
//		}
	}
//	a.debug();

	long long ans = 0;
	for (long long i = 1; i < n; i++)
	{
		//a.debug();
		long long A = a.pool[a.head].data[0];
		long long B = a.pool[a.head].data[1];
        a.del(a.head, 0);
		//cout<<"A:"<<A<<"  B:"<<B<<endl;
		a.del(a.head, 0);
		ans += A + B;
		a.push(A + B);
	}
	cout << ans;
	return 0;
}

就冲这一堆调试码你就知道我有多凌乱了

然后!

我无意中把主函数的计算部分改了一下

改成了这样:

long long ans = 0;
	for (long long i = 1; i < n; i++)
	{
		//a.debug();
		long long A = a.pool[a.head].data[0];
		a.del(a.head, 0);
		long long B = a.pool[a.head].data[0];
		//cout<<"A:"<<A<<"  B:"<<B<<endl;
		a.del(a.head, 0);
		ans += A + B;
		a.push(A + B);
	}

然后他就过了....过了....

我寻思着块状链表不是保证有序吗

直接取出第一第二再删

和取一个删一个就有区别了?

晕了

希望有大佬能指点一下,不胜感激qwq

2022/3/14 18:31
加载中...