#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ,d;
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
for(i=1;i<=n;i++)
{
p=(struct node *)malloc(sizeof(struct node));
cin>>p->data;
p->next=head->next;
head->next=p;
}
return head;
};
int main()
{
struct node *head,*p;
int n;
cin>>n;
head=creat(n);
p=head->next;
cout<<p->data;
p=p->next;
for(int i=1;i<n;i++)
{
cout<<" "<<p->data;
p=p->next;
}
cout<<endl;
return 0;
}
逆序建立链表 。注意头结点的移动跟输出格式
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ;
head=(struct node*)malloc(sizeof(struct node));
head->next=NULL;
tail=head;
for(i=1;i<=n;i++)
{
p=(struct node *)malloc(sizeof(struct node));
cin>>p->data;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
int main()
{
int n;
cin>>n;
struct node *head=creat(n);
struct node *p=head->next;
cout<<p->data;
p=p->next;
for(int i=1;i<n;i++)
{
cout<<" "<<p->data;
p=p->next;
}
cout<<endl;
return 0;
}
顺序建立链表 ,利用一个尾指针的移动来顺序的链接链表 。
1138按照数据输入的相反顺序(逆位序)建立一个单链表,并将单链表中重复的元素删除(值相同的元素只保留最后输入的一个)。
Input
第一行输入元素个数 n (1 <= n <= 15);
第二行输入 n 个整数,保证在 int 范围内。
Output
第一行输出初始链表元素个数;
第二行输出按照逆位序所建立的初始链表;
第三行输出删除重复元素后的单链表元素个数;
第四行输出删除重复元素后的单链表。
Example Input
10
21 30 14 55 32 63 11 30 55 30
Example Output
10
30 55 30 11 63 32 55 14 30 21
7
30 55 11 63 32 14 21
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ;
head=new node;
head->next=NULL;
tail=head;
for(i=1;i<=n;i++)
{
p=new node;
cin>>p->data;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
int dlt(struct node *head,int n,int key)
{
struct node*p,*q;
p=head->next;
q=head;
while(p!=NULL)
{
if(p->data==key)
{
q->next=p->next;
free(p);
p=q->next;
n--;
}
else
{
q=p;
p=p->next;
}
}
return n;
};
void show (struct node*head)
{
struct node*p=head->next;
while(p)
{
if(p->next!=NULL)
cout<<p->data<<" ";
else
cout<<p->data<<endl;
p=p->next;
}
}
int main()
{
int n,m,key;
cin>>n;
struct node *head=creat(n);
cin>>key;
cout<<n<<endl;
show(head);
m=dlt(head,n,key);
cout<<m<<endl;
show(head);
return 0;
}
把对链表的操作都打成函数,关键点删去key时使用q,p,两个节点保证删除后链表仍然链接,
双链表
学会了单向链表,我们又多了一种解决问题的能力,单链表利用一个指针就能在内存中找到下一个位置,这是一个不会轻易断裂的链。但单链表有一个弱点——不能回指。比如在链表中有两个节点A,B,他们的关系是B是A的后继,A指向了B,便能轻易经A找到B,但从B却不能找到A。一个简单的想法便能轻易解决这个问题——建立双向链表。在双向链表中,A有一个指针指向了节点B,同时,B又有一个指向A的指针。这样不仅能从链表头节点的位置遍历整个链表所有节点,也能从链表尾节点开始遍历所有节点。对于给定的一列数据,按照给定的顺序建立双向链表,按照关键字找到相应节点,输出此节点的前驱节点关键字及后继节点关键字。
Input
第一行两个正整数n(代表节点个数),m(代表要找的关键字的个数)。第二行是n个数(n个数没有重复),利用这n个数建立双向链表。接下来有m个关键字,每个占一行。
Output
对给定的每个关键字,输出此关键字前驱节点关键字和后继节点关键字。如果给定的关键字没有前驱或者后继,则不输出。
注意:每个给定关键字的输出占一行。
一行输出的数据之间有一个空格,行首、行末无空格。
Example Input
10 31 2 3 4 5 6 7 8 9 0350
Example Output
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next,*last;
};
struct node*creat (int n)
{
struct node *head,*p,*tail;
head=new node;
head->next=NULL;
head->last=NULL;
tail=new node;
tail=head;
for(int i=1;i<=n;i++)
{
p=new node;
p->next=NULL;
cin>>p->data;
tail->next=p;
p->last=tail;
tail=p;
}
return head;
};
int main()
{
int n,m,a;
struct node *head,*p;
cin>>n>>m;
head=creat(n);
for(int j=0;j<m;j++)
{
cin>>a;
p=head->next;
for(int i=0;i<n;i++)
{
if(p->data==a)
{
if(p->last==head)
cout<<p->next->data<<endl;
else if(p->next==NULL)
cout<<p->last->data<<endl;
else
cout<<p->last->data<<" "<<p->next->data<<endl;
break;
}
else
p=p->next;
}
}
return 0;
}
2120输入N个整数顺序建立一个单链表,将该单链表拆分成两个子链表,第一个子链表存放了所有的偶数,第二个子链表存放了所有的奇数。两个子链表中数据的相对次序与原链表一致。
Input
Output
第一行分别输出偶数链表与奇数链表的元素个数;
第二行依次输出偶数子链表的所有数据;
第三行依次输出奇数子链表的所有数据。
Example Input
10
1 3 22 8 15 999 9 44 6 1001
Example Output
4 6
22 8 44 6
1 3 15 999 9 1001
#include <bits/stdc++.h>
using namespace std;
int s1=0,s2=0;
struct node
{
int data;
struct node *next;
};
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ;
head=new node;
head->next=NULL;
tail=head;
for(i=1;i<=n;i++)
{
p=new node;
cin>>p->data;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
struct node*split(struct node *head1)
{
struct node *head2,*p,*q,*tail1,*tail2;
head2=new node;
head2->next=NULL;
tail1=head1;
p=head1->next;
head1->next=NULL;
q=p->next;
tail2=head2;
while(p!=NULL)
{
if(p->data%2==0)
{
s1++;
p->next=NULL;
tail1->next=p;
tail1=p;
}
else
{
s2++;
p->next=NULL;
tail2->next=p;
tail2=p;
}
p=q;
if(q!=NULL)
q=q->next;
}
return (head2);
}
void show (struct node*head)
{
struct node*p=head->next;
while(p)
{
if(p->next!=NULL)
cout<<p->data<<" ";
else
cout<<p->data<<endl;
p=p->next;
}
}
int main()
{
int n;
cin>>n;
struct node *head,*head2;
head=creat(n);
head2=split(head);
cout<<s1<<" "<<s2<<endl;
show(head);
show(head2);
return 0;
}
链表的插入
给出一个只有头指针的链表和 n 次操作,每次操作为在链表的第 m 个元素后面插入一个新元素x。若m 大于链表的元素总数则将x放在链表的最后。
Input
多组输入。每组数据首先输入一个整数n(n∈[1,100]),代表有n次操作。
接下来的n行,每行有两个整数Mi(Mi∈[0,10000]),Xi。
Output
对于每组数据。从前到后输出链表的所有元素,两个元素之间用空格隔开。
Example Input
Example Output
#include <bits/stdc++.h>
using namespace std;
int s1=0,s2=0;
struct node
{
int data;
struct node *next;
}*head;
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ;
head=new node;
head->next=NULL;
tail=head;
for(i=1;i<=n;i++)
{
p=new node;
cin>>p->data;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
void insert(int a,int b)
{
struct node *p,*q;
int s=0;
p=new node;
p=head->next;
while(p!=NULL&&s<a)
{
s++;
p=p->next;
}
q=new node;
q->data=b;
q->next=p->next;
p->next=q;
}
void show (struct node*head)
{
struct node*p=head->next;
while(p)
{
if(p->next!=NULL)
cout<<p->data<<" ";
else
cout<<p->data<<endl;
p=p->next;
}
}
int main()
{
int n,a,b;
cin>>n;
head=new node;
head->next=NULL;
for(int i=0;i<n;i++)
{
cin>>a>>b;
insert(a,b);
}
show(head);
return 0;
}[错误答案,]
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
int len;
void creatlist(struct node * head ,int m, int n)
{
struct node *p, *q;
int i;
p = head;
for (i = 0;i < m && i < len;i ++)
p = p -> next;
q=new node;
q->data=n;
q->next=p->next;
p->next=q;
len ++;
}
void show (struct node*head)
{
struct node*p=head->next;
while(p)
{
if(p->next!=NULL)
cout<<p->data<<" ";
else
cout<<p->data<<endl;
p=p->next;
}
}
int main()
{
int n,a,b;
while(cin>>n)
{
struct node* head=new node;
len=0;
for(int i=0;i<n;i++)
{
cin>>a>>b;
creatlist(head,a,b);
}
show(head);
}
return 0;
}正确答案 【】
修改过得正确答案。
01 | #include <bits/stdc++.h> |
13 | void inserrt( struct node *head, int a, int b) |
17 | for ( int i=0;i<a&&i<s;i++) |
25 | void show ( struct node*head) |
27 | struct node*p=head->next; |
2119分别输入两个有序的整数序列(分别包含M和N个数据),建立两个有序的单链表,将这两个有序单链表合并成为一个大的有序单链表,并依次输出合并后的单链表数据。
Input
第一行输入M与N的值;
第二行依次输入M个有序的整数;
第三行依次输入N个有序的整数。
Output
输出合并后的单链表所包含的M+N个有序的整数。
Example Input
6 5
1 23 26 45 66 99
14 21 28 50 100
Example Output
1 14 21 23 26 28 45 50 66 99 100
#include <bits/stdc++.h>
using namespace std;
int s1=0,s2=0;
struct node
{
int data;
struct node *next;
}*head;
struct node*creat (int n)
{
struct node *head,*p,*tail;
int i ;
head=new node;
head->next=NULL;
tail=head;
for(i=1;i<=n;i++)
{
p=new node;
cin>>p->data;
p->next=NULL;
tail->next=p;
tail=p;
}
return head;
};
struct node*merge(struct node*head1,struct node*head2)
{
struct node *p1,*p2,*tail;
p1=head1->next;
p2=head2->next;
tail=head1;
free(head2);
while(p1&&p2)
{
if(p1->data<p2->data)
{
tail->next=p1;
tail=p1;
p1=p1->next;
}
else
{
tail->next=p2;
tail=p2;
p2=p2->next;
}
}
if(p1)
tail->next=p1;
else
tail->next=p2;
return head1;
}
void show (struct node*head)
{
struct node*p=head->next;
while(p)
{
if(p->next!=NULL)
cout<<p->data<<" ";
else
cout<<p->data<<endl;
p=p->next;
}
}
int main()
{
int a,b;
cin>>a>>b;
struct node*head1,*head2;
head1=creat(a);
head2=creat(b);
head1=merge(head1,head2);
show(head1);
return 0;
}归并与拆分相对应。
2035请用链表完成下面题目要求。
xiaobai 很喜欢音乐,几年来一直在收集好听的专辑。他有个习惯,每次在听完一首音乐后会给这首音乐打分,而且会隔一段时间给打好分的音乐排一个名次。今天 xiaobai 打开自己的音乐文件夹,发现有很多不同时期打过分的排好序的子音乐文件夹,他想把这些音乐放到一块,组成一个分数有序的序列。由于音乐文件很多,而文件里音乐的数目也是不确定的,怎么帮帮 xiaobai 完成这件工作呢?
Input
输入数据第一行为一个整数n(n<1000),代表文件夹的数量。接下来是n个文件夹的信息,每个文件夹信息的第一行是一个数字m(m<=10000),代表这个文件夹里有m首歌,后面m行每行一个歌曲名、分数,之间用空格分开。歌曲名称不超过5个字符。
Output
输出一行,为所有音乐组成的一个序列,音乐只输出名字。
如果音乐分数相同则按照音乐名字典序进行排序。
Example Input
34aaa 60aab 50aac 40aad 302kkk 60kkd 593qow 70qwe 60qqw 20
01 | #include <bits/stdc++.h> |
结构体排序版本
09 | int cp( struct music a, struct music b)sort函数的使用cp函数来确定通过那种比较方式。struct的命名形参格式要注意。 |
11 | return a.score>b.score;明确了是返回大的值,所是从大到小比较, |
23 | cin>>a[x].name>>a[x].score; |
25 | t+=m;因为不是一次输入通过三次输入为了防止数值的覆盖每次对输入的次数进行累加。 |
28 | for ( int j=0;j<t-1;j++) |
30 | cout<<a[t-1].name<<endl; |
001 | #include <bits/stdc++.h> |
链表归并方法。
010 | struct node*creat( int n) |
012 | struct node *head,*tail,*p; |
020 | cin>>p->name>>p->score; |
027 | struct node*merge( struct node*head1, struct node*head2) |
029 | struct node*p1,*p2,*tail; |
036 | if (p1->score>p2->score) |
042 | else if (p1->score<p2->score) |
050 | if ( strcmp (p1->name,p2->name)<0) |
070 | void show ( struct node*head) |
072 | struct node*p=head->next; |
085 | struct node*head1,*head2; |
092 | head1=merge(head1,head2); |
1197n个人想玩残酷的死亡游戏,游戏规则如下:
n个人进行编号,分别从1到n,排成一个圈,顺时针从1开始数到m,数到m的人被杀,剩下的人继续游戏,活到最后的一个人是胜利者。
请输出最后一个人的编号。
Input
输入n和m值。
Output
输出胜利者的编号。
Example Input
Example Output
01 | #include<bits/stdc++.h> |
13 | struct node*p,*head,*tail; |
42 | cout<<tail->data<<endl; |
2056说到“敢死队”,大家不要以为我来介绍电影了,因为数据结构里真有这么道程序设计题目,原题如下:
有M个敢死队员要炸掉敌人的一个碉堡,谁都不想去,排长决定用轮回数数的办法来决定哪个战士去执行任务。如果前一个战士没完成任务,则要再派一个战士上去。现给每个战士编一个号,大家围坐成一圈,随便从某一个战士开始计数,当数到5时,对应的战士就去执行任务,且此战士不再参加下一轮计数。如果此战士没完成任务,再从下一个战士开始数数,被数到第5时,此战士接着去执行任务。以此类推,直到任务完成为止。
这题本来就叫“敢死队”。“谁都不想去”,就这一句我觉得这个问题也只能叫“不敢死队问题”。今天大家就要完成这道不敢死队问题。我们假设排长是1号,按照上面介绍,从一号开始数,数到5的那名战士去执行任务,那么排长是第几个去执行任务的?
Input
输入包括多试数据,每行一个整数M(0<=M<=10000)(敢死队人数),若M==0,输入结束,不做处理。
Output
Example Input
Example Output
01 | #include<bits/stdc++.h> |
15 | struct node*p,*head,*tail; |
3879 PBH 最近在玩一个游戏。游戏中玩家有 100 的血量,目前有 n 个小怪,小怪会按顺序前来攻击玩家且小怪只会采用 1v1 的方式,玩家每次可秒杀一个小怪,并受到小怪攻击力的伤害(血量减少小怪攻击力的数值),打死小怪会掉落药水。
现在问题来了,打完这 n 个小怪最少需要喝多少瓶药水(喝药水不耗时)?
Input
先输入一个整数 t 表示数据的组数,t 不超过 1000。
对于每组数据,第一行先输入小怪的个数 n (1 <= n <= 100),接下来的 n 行输入小怪攻击力 atki (1 <= atki <= 50) 以及小怪掉落 mi (0 <= mi <= 4) 个药水和药水所能恢复生命的值 ai (1 <= ai <= 30)。
Output
对于每组数据先输出 "Case #x: ",x 表示当前为第几组数据,之后输出打完所有小怪需要的最少药水数。如果无法杀死这 n 个小怪,即某次攻击小怪时已无药水可用且当前血量无法攻击小怪(小怪攻击大于等于当前血量),则输出 ”QAQ”。
所有输出均不包括引号。
Example Input
3
2
50 1 20
49 0
4
50 1 10
40 0
30 3 20 30 20
10 0
3
50 3 20 15 1
45 2 1 1
27 0
Example Output
Case #1: 0
Case #2: QAQ
Case #3: 2
01 | #include <bits/stdc++.h> |
13 | for (k=1;k<=t;k++)注意组数; |
17 | struct node*head,*p,*q; |
36 | if (q->next->data<p->data) |
48 | while (sum<=ak&&head->next!=NULL)血比攻击少并且血还有就得加血。 |
51 | head->next=p->next;sum+=p->data; |
65 | if (q->next->data<p->data) |
类似链表的归并,建立一个空指针,从head开始遍历,找到一个小于这个药的位置插入。
插入链表的过程 ,P->next=q->next;
q->next=p;
76 | cout<< "Case #" <<k<< ": " ; |
3874 4 月 20 日,火纹新作另一位英雄王 (Fire Emblem Echoes) 终于发售啦,本作作为 92 年火纹外传的复刻,游戏系统增加了大量的新元素以及优化(重点是 3DS 比 FC 画质不知道好到哪去了),同时也是系列发售 27 周年,真是个有纪念意义的日子呢!
新作可以在游戏中收集各种各样的物品,而今天 bLue 也要开始玩这个游戏,因为 bLue 每次使用物品都要翻看所有物品找出最合适的一个,物品的种类和数量又非常的多,每种物品都有价值 v 和重量 w 两种属性。他根据属性把每种物品都定义了一个优先级 p = v*1024+w,使用时只需要选择优先级最高的一个就可以了,但是这个工作量也是很多的,你能帮他完成么?
Input
多组输入,首先输入一个整数 T (1 <= T <= 100) 表示数据组数。
对于每组数据:
- 第一行输入 1 个整数 q (1 <= q <= 10000),表示操作次数
- 随后 q 行,每行表示一次操作,操作类型有 "add" 和 "use" 两种,输入格式如下:
- "add name v w" 添加一个物品到背包。name 表示物品的名称(不含空格且长度不超过 30),v (0 <= v < 1024) 表示物品的价值,w (0 <= w < 1024) 表示物品的重量(保证没有价值和重量都相同的物品)
- "use" 使用背包中优先级最高的物品,使用后物品从背包中消失
Output
对于每组数据:
- 每次 "use" 操作输出一行,表示被使用物品的信息。若背包为空,则输出 "The package is empty!"(不包含引号)
- q 次操作结束后,若背包不为空,则按照优先级从高到低的顺序输出背包中剩余的所有物品(格式同上,每个物品信息占一行)
Example Input
2
12
add HolySword 3 1
use
use
add Falchion 10 0
use
add BraveSword 5 0
add Astra 8 1
add RoyalSword 7 1
add DarknessSword 13 5
use
add Horseslayer 6 1
add Gradivus 15 1
2
add AC-Sword 0 0
use
Example Output
HolySword 3 1
The package is empty!
Falchion 10 0
DarknessSword 13 5
Gradivus 15 1
Astra 8 1
RoyalSword 7 1
Horseslayer 6 1
BraveSword 5 0
AC-Sword 0 0
18 | struct node*head,*p,*q; |
25 | if ( strcmp (direct, "add" )==0) |
29 | cin>>p->name>>p->v>>p->w; |
45 | cout<< "The package is empty!" <<endl; |
50 | cout<<p->name<< " " <<p->v<< " " <<p->w<<endl; |
57 | cout<<p->name<< " " <<p->v<< " " <<p->w<<endl; |
time limit .