oop练习(第12周)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值