oop
2018Final链表(龙舟队)
凤湖中学有一支优秀的龙舟队。在任意时刻,龙舟队里至少有3人,其中至少有1名鼓手。龙舟队的成员一直在调整中。鼓手的离队有可能导致队中暂时没有鼓手,这时,就要自动选择最有资历的队员作为鼓手。
现在用一个单链表来存储龙舟队成员的信息,每个成员信息包括是否为鼓手, 编号(所有成员的编号不相同)和年级:
链表中按先鼓手,后一般队员的顺序存储队员信息。如果有多个鼓手,则按他们的编号排序,编号较小者在前;一般队员也按编号从小到大的规则排序。
在自动选择鼓手时,优先选择年级最高的,如果有多位队员同时具有最高的年级号,则选择其中编号最小的那位作鼓手。
输入时,首先输入若干名队员信息,每条信息包括3项:是否鼓手(0否,1是),编号,年级。当输入-1时结束输入初始信息。接着,进行队员增减操作,每次增减操作最多可能包括4项:第一项为操作类型(0为减少,1为增加,-1为终止操作),如果第1项为-1,则终止输入;如果第1项为0,则输入离开的成员的编号(假设所输入的编号肯定在当前龙舟队中);如果第1项为1时,则输入新队员的3项信息:是否鼓手(0否,1是),编号(假设新加入成员的编号不会与现有成员相同),年级。
输出:在每次增减操作后,均输出当前龙舟队的前3位成员的信息(假设在建立链表后,任意时刻该链表中的结点数量均不会小于3)。
输入样例:
1 0 7
0 5 9
0 3 8
0 16 8
1 20 9
-1
0 0
0 20
-1
输出样例:
20 3 5
5 3 16
#include <iostream>
using namespace std;
struct Player{
bool drummer;
int num;
int grade;
Player* next;
};
void print(Player *head){
Player *p=head;
cout<<p->num<<' ';
p=p->next;
cout<<p->num<<' ';
p=p->next;
cout<<p->num<<endl;
}
#include<bits/stdc++.h>
using namespace std;
int cmp1(Player a, Player b) {
if (a.drummer == b.drummer) {
return a.num < b.num;
}
else {
return a.drummer > b.drummer;
}
}
int cmp2(Player a, Player b) {
return a.grade > b.grade;
}
Player a[10000];
int i;
Player* create() {
Player* head;
int flag;
for (i = 0; 1; i++) {
cin >> flag;
if (flag == -1)
break;
else {
a[i].drummer = flag;
cin >> a[i].num >> a[i].grade;
a[i].next = &a[i + 1];
}
}
sort(a, a + i, cmp1);
if (a[0].drummer == 0) {
sort(a, a + i, cmp2);
a[0].drummer = 1;
sort(a, a + i, cmp1);
}
for (int j = 0; j < i; j++) {
a[j].next = &a[j + 1];
}
a[i - 1].next = NULL;
head = &a[0];
return head;
}
Player* addPlayer(Player* head, Player* q) {
a[i - 1].next = &a[i];
a[i].drummer = q->drummer;
a[i].num = q->num;
a[i].grade = q->grade;
i++;
sort(a, a + i, cmp1);
for (int j = 0; j < i; j++) {
a[j].next = &a[j + 1];
}
a[i - 1].next = NULL;
head = &a[0];
return head;
}
Player* removePlayer(Player* head, int num) {
for (int j = 0; j < i; j++) {
if (a[j].num == num) {
a[j].drummer = 0;
a[j].num = 9999999;
a[j].grade = -1;
}
}
sort(a, a + i, cmp1);
if (a[0].drummer == 0) {
sort(a, a + i, cmp2);
a[0].drummer = 1;
sort(a, a + i, cmp1);
}
for (int j = 0; j < i; j++) {
a[j].next = &a[j + 1];
}
a[i - 1].next = NULL;
head = &a[0];
return head;
}
int main(){
Player *head=NULL;
int task, d, num, grade;
head=create();
while(1){
cin>>task;
if(task<0) break;
if(task==1){
Player*q = new Player;
cin>>d>>q->num>>q->grade;
if(d==1) q->drummer=true; else q->drummer=false;
q->next = NULL;
head=addPlayer(head, q);
}
if(task==0){
cin>>num;
head=removePlayer(head, num);
}
print(head);
}
return 0;
}
单链表最大值
本题要求求出单链表值最大的结点并返回。要求实现两个函数。
输入样例:
4
3 7 9 5
输出样例:
9
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
/* 建立单链表并返回单链表的头指针 */
struct Node* buildLinkedList(int* arr, int n);
/* 求单链表值最大的结点 */
struct Node* getMax(struct Node* head);
int main(int argc, char const *argv[])
{
int *a, n, i;
scanf("%d", &n);
a = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
struct Node* head = NULL;
head = buildLinkedList(a, n);
struct Node* pMax = getMax(head);
if (pMax)
printf("%d\n", pMax->data);
else
printf("-1\n");
free(a);
return 0;
}
struct Node* buildLinkedList(int* arr, int n){
struct Node *head, *p;
head = new(Node);
head->next = NULL;
for (int i = 0; i < n; i++){
p = new(Node);
p->data = arr[i];
p->next = head->next;
head->next = p;
}
return head;
}
struct Node* getMax(struct Node* head){
struct Node* p1;
struct Node* p2;
p1 = head->next;
p2 = p1->next;
while(p2){
if(p2->data > p1->data){
p1 = p2;
p2 = p2->next;
}
else{
p2 = p2->next;
}
}
return p1;
}
工作备忘录的生成(链表)
每天都要处理很多事务,为了更好地安排工作,希望在每天开始工作前,根据工作记录,生成工作备忘录。首先输入工作记录数(大于0的一个整数),再逐条输入各条工作记录,每条工作记录包括:工作名,开始时间,结束时间。假设每项工作的开始时间均小于它的结束时间,并且各项工作的开始时间互不相同。
我们的工作是需要把这些工作记录按开始时间排序并输出,在输出时,如果某项工作与若干项工作冲突(在做该项工作时,需要同时做其它工作),则在该工作名前加’*’。
输入样例:
4
aaa 19 20
ccc 169 200
ddd 153 170
bbb 20 111
输出样例:
aaa 19 20
bbb 20 111
*ddd 153 170
*ccc 169 200
#include<iostream>
#include <string>
using namespace std;
struct Node{
string name;
int start;
int end;
Node *next;
};
Node* add(Node *, Node *);
void display(Node *);
bool check(Node *head)
{
if(head==NULL || head->next==NULL) return true;
Node *p=head->next;
if(head->start > p->start) return false;
return check(p);
}
int main()
{
Node *head=NULL, *p;
int i, repeat;
cin>>repeat;
for(i=0;i<repeat;i++){
p = new Node;
cin>>p->name>>p->start>>p->end;
p->next=NULL;
head = add(head, p);
}
if(!check(head)) cout<<"ERROR"<<endl;
display(head);
return 0;
}
Node* add(Node *head, Node *p) {
Node* a = head, * b = head;
while ((a != NULL) && (a->start < p->start)) {
b = a;
a = a->next;
}
if (a == head) {
p->next = head;
head = p;
}
else {
p->next = a;
b->next = p;
}
return head;
}
void display(Node *head) {
Node *p = head, *q;
int flag;
while (p != NULL) {
flag = 0;
q = head;
while ((flag == 0) && q != p) {
if (q->end > p->start) {
flag = 1;
break;
}
q = q->next;
}
q = p->next;
while ((flag == 0) && (q != NULL)) {
if (p->end > q->start) {
flag = 1;
break;
}
q = q->next;
}
if (flag == 1) {
cout << "*";
}
cout << p->name << " " << p->start << " " << p->end << endl;
p = p->next;
}
}
查找学生链表
输入样例1:
20180002 王红
20180006 张勇
20180008 吴涛
20170010 林玉
-1 xx
20180002
输出样例1:
在这里给出相应的输出。例如:
王红
输入样例2:
20180002 王红
20180006 张勇
20180008 吴涛
20170010 林玉
-1 xx
20170015
输出样例2:
Not Found!
#include<bits/stdc++.h>
using namespace std;
List * CreateList(){
List *head = NULL ,*p1, *p2;
head = p1 =p2 = new(List);
while(1){
cin >> p1->sno >> p1->sname;
if(p1->sno == -1)
break;
p2->next = p1;
p2=p1;
p1= new(List);
p2->next = NULL;
}
return head;
}
List *Find(List *head, int no){
List *p1 = head;
while(p1 && p1->sno != no){
p1 = p1-> next;
}
return p1;
}
int main(void){
List *list=NULL,*p;
int no;
list=CreateList();
while(~scanf("%d", &no))
{
p=Find(list,no);
if( p ) printf("%s\n", p->sname);
else printf("Not Found!\n");
}
return 0;
}
单链表(流浪狗收养所)
怡山小学生物组的同学在课外要收养一批流浪狗。在流浪狗进入收养基地时,课外指导老师会给每一只狗取一个唯一的编号,并且判定它的年龄,让组长输入流浪狗档案。档案以单链表存储,按年龄为序(从小到大),如果年龄相同,则后录入的记录应该放在前面。
由于组里新来了一位二年级的淘气组员小林,喜欢将已经输入的档案再次输入。他在输入时,会输入正确的编号,却可能输入错误的年龄(但他所输入的年龄不会大于真实的年龄),因此在输入档案外,组长还需要对档案进行清理,清除那些重复档案。
输入时:首先输入任务类型:1代表插入新的记录, 2代表清理档案, 0代表退出。如果需要加入新的记录,则接下来将依次输入编号和年龄。
输出时:按照从前到后的顺序输出档案中的所有的记录,每条记录单独占一行。
输入样例:
1 abcd 2
1 cd 5
1 cd 4
1 zz 4
2
0
输出样例:
abcd 2
abcd 2
cd 5
abcd 2
cd 4
cd 5
abcd 2
zz 4
cd 4
cd 5
abcd 2
zz 4
cd 5
#include <iostream>
#include <string>
using namespace std;
struct Dog{
string no;
int age;
Dog *next;
};
Dog *head=NULL;
void *del(Dog *p){
if(p!=NULL) {
del(p->next);
delete p;
}
}
void display(Dog *p){
if(p!=NULL){
cout<<p->no<<' '<<p->age<<endl;
display(p->next);
}
}
Dog *clear();
Dog *insert(string &no, int age);
int main()
{
int task, age;
string no;
cin>>task;
while(task>0){
switch(task){
case 1:cin>>no>>age; head=insert(no, age); display(head); break;
case 2:head=clear(); display(head); break;
}
cin>>task;
}
del(head);
return 0;
}
Dog* insert(string& no, int age) {
Dog* p1, * p;
p = head;
p1 = new(Dog);
p1->no = no;
p1->age = age;
p1->next = NULL;
if (head == NULL) {
p1->next = NULL;
head = p1;
}
else {
if (head->age >= age) {
p1->next = head;
head = p1;
}
else {
int flag = 0;
while (p != NULL) {
if (p->age >= age) {
flag = 1;
break;
}
p = p->next;
}
if (flag) {
Dog* q = head;
while (q != NULL) {
if (q->next == p) {
q->next = p1;
p1->next = p;
break;
}
q = q->next;
}
}
else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = p1;
}
}
}
return head;
}
Dog* clear() {
Dog* p, * q, * r;
p = head;
while (p != NULL) {
q = p;
while (q->next != NULL) {
if (q->next->no == p->no) {
if (p == head) {
head = p->next;
break;
}
else {
r = head;
while (r->next != p)
r = r->next;
r->next = p->next;
break;
}
}
else
q = q->next;
}
p = p->next;
}
return head;
}
学生信息输入输出 (10分)
输入若干个学生的信息(学号、姓名、成绩),当输入学号为0时结束,用单向链表组织这些学生信息后,再按顺序输出。
输入样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
输出样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
#include<bits/stdc++.h>
using namespace std;
struct student {
int num;
char name[500];
int score;
student* next;
};
student* create() {
student* p1, * head, * p2;
p1 = new(student);
p2 = p1;
int n = 0;
int numm;
while (1) {
cin >> numm;
if (numm == 0)
break;
else
p1->num = numm;
cin >> p1->name >> p1->score;
n++;
if (n == 1) {
head = p1;
p2->next = NULL;
}
else {
p2->next = p1;
}
p2 = p1;
p1 = new(student);
}
p2->next = NULL;
return head;
}
void print(student* head) {
student* p;
p = head;
while (p != NULL) {
cout << p->num << " " << p->name << " " << p->score << endl;
p = p->next;
}
}
int main() {
student* head;
head = create();
print(head);
return 0;
}
成绩大于等于某值的学生信息输出 (10分)
输入若干个学生信息(包括学号、姓名和成绩),输入学号为0时输入结束,建立一个单向链表,再输入一个成绩值,将成绩大于等于该值的学生信息输出。
提示:
定义函数struct stud_node *Creat_Stu_Doc()完成创建链表
定义函数struct stud_node DeleteDoc(struct stud_node head,int min_score)将分数低于min_score的结点删除
定义函数void Ptrint_Stu_Doc(struct stud_node *head)打印链表
输入输出示例:括号内为说明,无需输入输出
输入样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
80
输出样例:
2 wang 80
4 zhao 85
#include<bits/stdc++.h>
using namespace std;
struct student {
int num;
char name[500];
int score;
student* next;
};
student* create() {
student* p1, * head, * p2;
p1 = new(student);
p2 = p1;
int n = 0;
int numm;
while (1) {
cin >> numm;
if (numm == 0)
break;
else
p1->num = numm;
cin >> p1->name >> p1->score;
n++;
if (n == 1) {
head = p1;
p2->next = NULL;
}
else {
p2->next = p1;
}
p2 = p1;
p1 = new(student);
}
p2->next = NULL;
delete p1;
return head;
}
void print(student* head,int sc) {
student* p;
p = head;
while (p != NULL) {
if (p->score >= sc)
cout << p->num << " " << p->name << " " << p->score << endl;
p = p->next;
}
}
int main() {
student* head;
int sc;
head = create();
cin >> sc;
print(head, sc);
return 0;
}
单向链表1 (10分)
链表节点定义为: struct Node{ int data; struct Node *next; }
编程实现:输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算: 输入若干个正整数(输入-1为结束标志),建立一个单向链表,将其中的奇数值结点删除后输出
输入输出示例:括号内为说明
输入样例:
2 (repeat=2)
1 2 3 4 5 6 7 -1
1 3 5 -1
输出样例:
2 4 6
#include<bits/stdc++.h>
using namespace std;
struct node {
int data;
node* next;
};
int main() {
int re;
cin >> re;
while (re--) {
int i;
node a[500];
for (i = 0; 1; i++) {
int na;
cin >> na;
if (na == -1)
break;
else
a[i].data = na;
a[i].next = &a[i + 1];
}
a[i - 1].next = NULL;
node* p;
p = &a[0];
int flag = 1;
while (p != NULL) {
if ((p->data % 2) == 0) {
if (flag) {
cout << p->data;
flag = 0;
}
else
cout << " " << p->data;
}
p = p->next;
}
if (flag == 0)
cout << endl;
}
return 0;
}
单向链表3 (10分)
编程实现:输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入一个正整数 n(0<n<=9)和一组(n个)升序的整数,建立单向链表,再输入一个整数 x,把 x 插入到这组数据中,使该组数据仍然有序。
输入输出示例:括号内为说明
输入样例:
4 (repeat=4)
5 (数据的个数n=5)
1 2 4 5 7 (5个有序整数)
3 (待插入整数x=3)
4 (数据的个数n=4)
1 2 5 7 (4个有序整数)
-10 (待插入整数x=-10)
3 (数据的个数n=3)
1 2 4 (3个有序整数)
100 (待插入整数x=100)
5 (数据的个数n=5)
1 2 4 5 7 (5个有序整数)
4 (待插入整数x=4)
输出样例:
size=6:1 2 3 4 5 7
size=5:-10 1 2 5 7
size=4:1 2 4 100
size=6:1 2 4 4 5 7
#include<bits/stdc++.h>
using namespace std;
struct node {
int data;
node* next;
};
int cmp(node a, node b) {
return a.data < b.data;
}
int main() {
int re;
cin >> re;
while (re--) {
int i, n;
node a[500];
cin >> n;
for (i = 0; i < n; i++) {
cin >> a[i].data;
a[i].next = &a[i + 1];
}
int x;
cin >> x;
a[n].data = x;
a[n].next = NULL;
sort(a, a + n + 1,cmp);
for (int j = 0; j < n+1; j++) {
a[j].next = &a[j + 1];
}
a[n].next = NULL;
cout << "size=" << n + 1 << ":";
node* p;
p = &a[0];
while (p != NULL) {
if (p->next == NULL) {
cout<<p->data;
}
else {
cout << p->data << " ";
}
p = p->next;
}
cout << endl;
}
return 0;
}
单向链表4
定义单向链表:输入若干个正整数(输入-1为结束标志),要求按输入数据的逆序并输出。
输入输出示例:括号内为说明
输入样例:
1 2 3 4 5 6 7 -1
输出样例:
7 6 5 4 3 2 1
#include<bits/stdc++.h>
using namespace std;
struct node {
node* former;
int data;
node* next;
};
int main() {
node* head, * p1, * end;
p1 = new(node);
end = p1;
int data, n = 0;
while (1) {
cin >> data;
if (data == -1)
break;
p1->data = data;
n++;
if (n == 1) {
head = p1;
head->former = NULL;
end->next = NULL;
}
else {
end->next = p1;
p1->former = end;
}
end = p1;
p1 = new(node);
}
end->next =NULL;
p1 = NULL;
p1 = end;
int flag = 1;
while (p1 != NULL) {
if (flag) {
cout << p1->data;
flag = 0;
}
else
cout << " " << p1->data;
p1 = p1->former;
}
return 0;
}
单向链表5 (10分)
定义单向链表struct Node并实现:输入若干个学生信息(包括学号、姓名和成绩),输入学号为0时输入结束,再输入一个成绩值,将成绩小于该值的学生信息删除,并将成绩大于等于该值的学生信息输出。
输入输出示例:括号内为说明
输入样例:
1 zhang 78
2 wang 80
3 li 75
4 zhao 85
0
80
输出样例:
2 wang 80
4 zhao 85
#include<bits/stdc++.h>
using namespace std;
struct student {
int num;
char name[500];
int score;
student* next;
};
student* create() {
student* p1, * head, * p2;
p1 = new(student);
p2 = p1;
int n = 0;
int numm;
while (1) {
cin >> numm;
if (numm == 0)
break;
else
p1->num = numm;
cin >> p1->name >> p1->score;
n++;
if (n == 1) {
head = p1;
p2->next = NULL;
}
else {
p2->next = p1;
}
p2 = p1;
p1 = new(student);
}
p2->next = NULL;
delete p1;
return head;
}
void print(student* head,int sc) {
student* p;
p = head;
while (p != NULL) {
if (p->score >= sc)
cout << p->num << " " << p->name << " " << p->score << endl;
p = p->next;
}
}
int main() {
student* head;
int sc;
head = create();
cin >> sc;
print(head, sc);
return 0;
}
链表也简单final (25分)
将学生成绩绩点组成一个链表。链表结构如下:
struct student {
string name; //学生姓名
double gpa; //绩点
student *next;
};
输入是一组学生的姓名和绩点,以链表形式存储。 删除绩点小于平均绩点的学生结点,成为一个新链表。 后按照输入的顺序,依序输出新链表的学生信息。平均绩点是输入的所有学生绩点取算术平均值。
输入格式:
输入包括若干行。 每行是一个学生的 姓名和绩点,以空格隔开。
最后一行是-1。
输出格式:
输出包括学生姓名。 每个学生姓名一行。
输入样例:
zhang 3.5
liu 2.1
tie 1.9
-1
输出样例:
zhang
#include<bits/stdc++.h>
using namespace std;
double sum = 0;
int n;
struct student {
string name;
double gpa;
student* next;
};
student* create() {
student* head, * p1, * p2;
p1 = new(student);
p2 = p1;
while (1) {
string a;
cin >> a;
if (a[0] == '-')
break;
(p1->name).assign(a);
cin >> p1->gpa;
n++;
sum += p1->gpa;
if (n == 1) {
head = p1;
p2->next = NULL;
}
else {
p2->next = p1;
}
p2 = p1;
p1 = new(student);
}
p2->next = NULL;
delete p1;
return head;
}
void move(student* head, double avg) {
student* p1, * p2;
p1 = head;
while (p1 != NULL) {
if (p1->gpa < avg) {
if (p1 == head)
head = p1->next;
else {
p2->next = p1->next;
}
}
else {
p2 = p1;
}
p1 = p1->next;
}
}
void print(student* head) {
student* p;
p = head;
while (p != NULL) {
cout << p->name << endl;
p = p->next;
}
}
int main() {
student* head;
head = create();
double avg = sum / (n * 1.0);
move(head, avg);
print(head);
return 0;
}