这个题我的第一想法就是做一个环状结构的链表出来。
如图
关于对闭合链表的建设,跟正常链表产不多,只是将最后的指针指向了链表头。
然后就是关于题目,题目中有说,学姐们不能喝醉,也就是每次的酒轮到学姐喝的时候就会跳过,也就是说关于我们现在已知的条件,对学姐的位置进行处理十分麻烦且不简洁,条件多的更好处理,也就是学长的座位,反正知道学长学姐的人数,所以可以先让链表中全是学姐,之后再根据已有的条件安排学长的位置。
#include<stdio.h>
#include<stdlib.h>
struct p//定义的一个结构体
{
struct p *next;
char c;
};
struct p * insert(int n)
{
struct p *head,*p,*q;
head=NULL;
char m;
for(int i=1; i<=2*n; i++)
{
p=(struct p *)malloc(sizeof(struct p));
p->c='G';//因为学姐不能喝醉,所以后续条件中加入学姐比较困难,所以一开始直接让学姐占据
//整个链表
p->next=NULL;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
if(i==2*n)
p->next=head;//这个就是将最后一个指针指向链表头,形成闭合链表的关键
}
return head;
}
关于下面这段代码我的想法是,现在我是让每个座位上都坐了一个学姐,其实也可以不坐学姐,直接让这个座位为空的,然后让酒杯转t下,直接轮到哪个位置,就放一个怨种学长(bushi)喝倒,但是这样最后还要请学姐再入坐,有点浪费时间,倒不如在建立链表的时候就让学姐入座,
这样只要碰到要喝酒的位置就让学长上。
int main()
{
struct p * insert(int n);
int n,t;
while(scanf("%d%d",&n,&t)!=EOF)//循环输入
{
struct p *head,*m;
m=head=insert(n);//让指针全部指向链表头
int count=0,x=0;//x相当于学长的人数
while(n!=x)//也就是说安排的学长的位置等于人数的时候结束循环
{
if(m->c!='B')//不是喝倒的学长
{
count++;
if(count==t)
{
x++;
count=0;
m->c='B';//这个也就相当于已经喝倒的学长
}
}
m=m->next;//指向下一个
}
然后就是对格式的要求
int v=0;
for(int i=0; i<2*n; i++)
{
printf("%c",head->c);
v++;
if(v==50)//满足50个字符一行的格式要求
{
printf("\n");
v=0;
}
head=head->next;
}
printf("\n\n");
}
return 0;
}
最后关于样例的输入与输出
今天写的题这个印象比较深(因为链表我不怎么会用)
所以除了用指针做的链表,我又在《啊哈!算法》中看了用数组构成的链表;
运用两个数组,第一个数组用来存放数据,第二个数组我理解的意思是,更像是一个导航或者说是地图,根据这个数组我就能在第一个数组中找到我想要的数值;
然后关于这两个数组运用的规律来讲,书上写的是第二个数组是用来存放当前序列中每一个元素右边的元素在第一个数组中的位置,例如:第二个数组中的1号元素,就代表当前序列中一号元素右边的元素存放在第一和数组的第二个元素内;
但是说实话,我没怎么看懂,但我自己研究了一会,我用自己的话来说就是,放平时啥用也没有,只有插入时有用;
而且我感觉这个链表超级不灵活,数值变化次数也多,容易出错;
#include<stdio.h>
int main()
{
int data[101],right[101];
int i,n,t,len;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&data[i]);
len=n;
for(i=1;i<=n;i++)
{
if(i!=0)
right[i]=i+1;
else
right[i]=0;
}
len++;
scanf("%d",&data[len]);
t=1;
while(t!=0)
{
if(data[right[t]]>data[len])
{
right[len]=right[t];
right[t]=len;
break;
}
t=right[t];
}
t=1;
for(int i=0;i<len;i++)
{
printf("%d ",data[t]);
t=right[t];
}
return 0;
}
输出结果