Farey序列
Description
Farey序列是一个这样的序列:其第一级序列定义为(0/1,1/1),这一序列扩展到第二级形成序列(0/1,1/2,1/1),扩展到第三极形成序列(0/1,1/3,1/2,2/3,1/1),扩展到第四级则形成序列(0/1,1/4,1/3,1/2,2/3,3/4,1/1)。以后在每一级n,如果上一级的任何两个相邻分数a/c与b/d满足(c+d)<=n,就将一个新的分数(a+b)/(c+d)插入在两个分数之间。对于给定的n值,依次输出其第n级序列所包含的每一个分数。
Input
输入一个整数n(0<n<=100)
Output
依次输出第n级序列所包含的每一个分数,每行输出10个分数,同一行的两个相邻分数间隔一个制表符的距离。
Sample
Input
6
Output
0/1 1/6 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4
4/5 5/6 1/1
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int a;
int b;
struct node* next;
}chain;
void add(chain* head,int n)//插入操作
{
chain* p, * q,*r;
p= head->next;
while (p->next)
{
q = p->next;
if (q->b + p->b <= n)
{
r = (chain*)malloc(sizeof(chain));
r->a = q->a + p->a;
r->b = q->b + p->b;
p->next = r;
r->next = q;
}
p = p->next;
}
}
void print(chain* head)//打印操作
{
chain* q;
q = head->next;
int sum = 0;
while (q)
{
sum++;
if(sum!=10)
printf("%d/%d\t", q->a, q->b);
else
{
sum = 0;
printf("%d/%d\n", q->a, q->b);
}
q = q->next;
}
}
int main()
{
chain* head, * p1, * p2;
head = (chain*)malloc(sizeof(chain));
head->next = NULL;
int n;
scanf("%d", &n);
p1 = (chain*)malloc(sizeof(chain));
p2 = (chain*)malloc(sizeof(chain));
p2->next = head->next;
head->next = p1;
p1->next = p2;
p1->a = 0;
p1->b = p2->a = p2->b = 1;
for (int i = 2; i <= n; i++)
add(head, i);
print(head);
return 0;
}
双向链表
Description
学会了单向链表,我们又多了一种解决问题的能力,单链表利用一个指针就能在内存中找到下一个位置,这是一个不会轻易断裂的链。但单链表有一个弱点——不能回指。比如在链表中有两个节点A,B,他们的关系是B是A的后继,A指向了B,便能轻易经A找到B,但从B却不能找到A。一个简单的想法便能轻易解决这个问题——建立双向链表。在双向链表中,A有一个指针指向了节点B,同时,B又有一个指向A的指针。这样不仅能从链表头节点的位置遍历整个链表所有节点,也能从链表尾节点开始遍历所有节点。对于给定的一列数据,按照给定的顺序建立双向链表,按照关键字找到相应节点,输出此节点的前驱节点关键字及后继节点关键字。
Input
第一行两个正整数n(代表节点个数),m(代表要找的关键字的个数)。第二行是n个数(n个数没有重复),利用这n个数建立双向链表。接下来有m个关键字,每个占一行。
Output
对给定的每个关键字,输出此关键字前驱节点关键字和后继节点关键字。如果给定的关键字没有前驱或者后继,则不输出。
注意:每个给定关键字的输出占一行。一行输出的数据之间有一个空格,行首、行末无空格。
Sample
Input
10 3
1 2 3 4 5 6 7 8 9 0
3
5
0
Output
2 4
4 6
9
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node* qian;
struct node* hou;
}chain;
chain* set(int n)//建表
{
chain* head, * p, * q, * end;
head = (chain*)malloc(sizeof(chain));
head->hou = NULL;
end = head;
for (int i = 0; i < n; i++)
{
p = (chain*)malloc(sizeof(chain));
scanf("%d", &p->data);
p->hou = end->hou;
end->hou = p;
p->qian = end;
end = p;
}
return head;
}
int main()
{
int n, m, i, x;
chain* head, * p, * q, * end;
scanf("%d %d", &n, &m);
head = set(n);
for (i = 0; i < m; i++)
{
scanf("%d", &x);
q = head->hou;
q->qian = NULL;
while (q)
{
if (q->data == x)
{
if (q->hou == NULL)
printf("%d\n", q->qian->data);
else if (q->qian == NULL)
printf("%d\n", q->hou->data);
else printf("%d %d\n", q->qian->data, q->hou->data);
}
q = q->hou;
}
}
return 0;
}
说明
这一次补一下链表中的两个题,也是用C写的。