链表专题:今天你ak了吗?②

大家好,欢迎来到今天你ak了吗系列,我是解说员,***。

欲先AK,先学链表。这里有链表的简介,不了解的可以自行查看。

先上题


t1是很简单的链表基础,板子题。代码自己研究。

//t1 AC代码
#include<bits/stdc++.h>
using namespace std;
int a[10100],b[10100],n,m,cnt,frt;
int main() {
	scanf("%d%d",&n,&m);
	cnt=n,frt=1;
	for(int i=1; i<=n; i++) {
		int tmp;
		scanf("%d",&tmp);
		a[i]=tmp;
		b[i-1]=i;
	}
	while(m--) {
		int p,q,c;
		scanf("%d%d",&c,&p);
		if(c==1) {
			if(p==frt)frt=b[frt];
			for(int i=frt,tot=1;;i=b[i],tot++)
			{
				if(tot==p-1)
				{			
					a[b[i]]=0;
					int tmp=b[i];
					b[i]=b[b[i]];
					b[tmp]=0;
					break;
				}
			}
			cnt--;
		} 
		else {
			scanf("%d",&q);
			a[++n]=q;
			for(int i=frt,tot=1;;i=b[i],tot++)
			{
				if(tot!=p)continue;
				b[n]=b[i];
				b[i]=n;
				++cnt;
				break;
			}
		}
	}
	for(int i=frt;a[i]!=0;i=b[i])
	{
		printf("%d ",a[i]);
	}
	printf("
");
	return 0;
}

如有疑问,可以在评论区留言。


t2是道特别经典的链表题,主要思路就是一个循环链表,然后不停的抹除数据就好了。
这里我给出一个黑科技做法:队列
队列很适用于做部分链表题,像这种约瑟夫问题。实际上这三道题都有很多人用队列求解。
先给个代码:

//t2 AC代码
#include<bits/stdc++.h>
using namespace std;
int ans[10000],n,m,tot=0;
queue<int> p;
queue<int> q;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)q.push(i);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<m;j++)
		{
			p.push(q.front());
			q.pop();
			if(q.empty())
			{
				q.push(p.front());
				p.pop();
			}
		}
		ans[++tot]=q.front();
		q.pop();
		while(!p.empty())
		{
			q.push(p.front());
			p.pop();
		}
	}
	for(int i=1;i<=tot;i++)printf("%d ",ans[i]);
	printf("
");
	return 0;
}

主要思想就是
依题意得每过(m)次报数就会出列一个人。
那么让他们一开始就入队列(p)中,每报一个数就将报数的这个人入队列(q)。报到第m个人,不入队列(q),入ans数组,然后出原队列(p)
方才入队列(q)的也全部出队列,入回原队列(p),然后开启下一次循环。


如果(p)队列空了还没有报够数,那么开启下一次循环(我的意思是让(q)出队列一个给(p),这样就又可以继续来且依旧是按照题目要求循环不懂得可以自己推一下)

注:这里的图m=5,n=6
最后输出ans数组就好了。


t3是链表和图结合了,说人话就是链式前向星。很容易就可以看出这是链式前向星。直接贴代码了。

#include<bits/stdc++.h>
#define MAXN 1000000
using namespace std;
int head[MAXN/10],cnt,m,n;
struct edge
{
	int to,nxt;
}e[MAXN*5];
void add(int u,int v)
{
	e[++cnt].to=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	for(int i=1;i<=n;i++)
	{
		int tmp[MAXN/10],t_=0;
		for(int j=head[i];j!=0;j=e[j].nxt)
		{
			tmp[++t_]=e[j].to;
		}
		for(int j=t_;j>=1;j--)printf("%d ",tmp[j]);
		printf("
");
	}
	return 0;
	
}

后期这篇博客还会进行些许更细节的更新,敬请期待……

原文地址:https://www.cnblogs.com/riced/p/14333196.html