函数+编程题
7-1 交换二叉树中每个结点的左孩子和右孩子
#include<stdio.h>
#include<stdlib.h>
typedef struct Node {
char data;
struct Node *left, *right;
} Node, *Tree;
Tree create() {
char ch;
Tree tree = NULL;
if (scanf("%c", &ch)) {//当有输入时
if (ch != '#') {
tree = (Tree)malloc(sizeof(Node));
tree->data = ch;
tree->left = create();
tree->right = create();
} else {
tree = NULL;
}
}
return tree;
}
void order(Tree tree) {
if (!tree)
return;
order(tree->left);
printf("%c", tree->data);
order(tree->right);
}
void swap(Tree tree) {
if (!tree)
return;
if (!tree->left && !tree->right)
return;
Tree tmp = tree->left;
tree->left = tree->right;
tree->right = tmp;
swap(tree->left);
swap(tree->right);
}
int main() {
Tree tree = create();
order(tree);
printf("\n");
swap(tree);
order(tree);
return 0;
}
7-2 两个有序链表序列的合并
一开始用的是数组方法
#include<stdio.h>
#include<stdlib.h>
int s1[1010], s2[1010];
int x, cnta, cntb;
int cmp(const void *a, const void *b){
return(*(int*)a - *(int*)b);
}
int main(){
while(scanf("%d", &x) != EOF){
if(x == -1) break;
else s1[++ cnta] = x;
}
while(!scanf("%d", &x) != EOF){
if(x == -1) break;
else s2[++ cntb] = x;
}
for(int i = cnta + 1; i <= cnta + cntb; i ++ ){
s1[i] = s2[i - cnta];
}
qsort(s1, cnta + cntb, sizeof(s1[0]), cmp);
if(cnta + cntb == 0){
printf("NULL");
return 0;
}
for(int i = 1; i <= cnta + cntb; i ++ ){
if(i != 1) printf(" ");
printf("%d", s1[i]);
}
后来发现在大规模输入的时候不能过
于是就借鉴网上的ac了嘤嘤嘤嘤QAQ
#include<stdio.h>
#include<stdlib.h>
typedef struct Node *List;
struct Node{
int data;
struct Node *Next;
};
List InitList(){
List l;
l = (List)malloc(sizeof(struct Node));
if(!l) return NULL;
l->Next = NULL;
return l;
}
void read(List l){
List t;
int data;
scanf("%d", &data);
while(data > 0){
t = (List)malloc(sizeof(struct Node));
if(!t) return ;
t->data = data;
t->Next = NULL;
l->Next = t;
l = l->Next;
scanf("%d", &data);
}
return ;
}
void combine(List l1, List l2, List l3){
l1 = l1->Next;
l2 = l2->Next;
while(l1 != NULL && l2 != NULL){
if(l1->data > l2->data){
l3->Next = l2;
l2 = l2->Next;
}
else{
l3->Next = l1;
l1 = l1->Next;
}
l3 = l3->Next;
}
if(l1 == NULL && l2 == NULL) return ;
if(l1 != NULL) l3->Next = l1;
else l3->Next = l2;
return ;
}
void print(List l){
l = l->Next;
if(l == NULL){
printf("NULL");
return ;
}
while(l){
if(l->Next == NULL) printf("%d", l->data);
else printf("%d ", l->data);
l = l->Next;
}
}
int main(){
List l1, l2, l3;
l1 = InitList();
l2 = InitList();
l3 = InitList();
read(l1);
read(l2);
combine(l1, l2, l3);
print(l3);
return 0;
}
6-4 链表逆置
struct ListNode *reverse( struct ListNode *head ){
struct ListNode *q, *p = head, *tail = NULL;
while(p){
q = (struct ListNode*)malloc(sizeof(struct ListNode));
q->data = p->data;
if(tail == NULL) q->next = NULL;
else q->next = tail;
tail = q;
p = p->next;
}
return tail;
}
6-1 顺序表基本操作
bool ListInsert(SqList *&L,int i,ElemType e){
if(i <= 0 || i > L->length + 1 || L->length == MaxSize) return false;
i -- ;
if(i == L->length){
L->data[i] = e;
L->length ++ ;
}
else{
for(int j = L->length; j > i; j -- ) L->data[j] = L->data[j - 1];
L->data[i] = e;
L->length ++ ;
//e = L->data[i - 1];
}
return true;
}
bool ListDelete(SqList *&L,int i,ElemType &e){
if(i < 1 || i > L->length) return false;
i -- ;
e = L->data[i];
for(int j = i; j < L->length; j ++ ) L->data[j] = L->data[j + 1];
L->length -- ;
return true;
}
bool ListDeleteElem(SqList *&L,ElemType e){
int i = 0, j = 0, flag = 0;
while(i + j < L->length){
L->data[i] = L->data[i + j];
if(L->data[i] == e){
j ++ ;
flag = 1;
}
else i ++ ;
}
L->length = L->length - j;
if(flag == 0) return false;
return true;
}
7-1 列车调度
循环遍历就会导致超时
#include<stdio.h>
#include<stdlib.h>
int n, cnt = 1;
int a[100010], t[100010];
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i ++ ){
scanf("%d", &a[i]);
}
t[0] = a[0];
for(int i = 1; i < n; i ++ ){
for(int j = 0; j < cnt; j ++ ){
if(t[j] > a[i]){
t[j] = a[i];
break;
}
else if(j == cnt - 1){
t[cnt ++ ] = a[i];
break;
}
}
}
printf("%d", cnt);
return 0;
}
所以就需要用二分法来解决; 用到了查找精确值的二分法
#include<stdio.h>
#include<stdlib.h>
int n, cnt = 1;
int main(){
scanf("%d", &n);
int a[n], t[n];
for(int i = 0; i < n; i ++ ){
scanf("%d", &a[i]);
}
t[0] = a[0];
for(int i = 1; i < n; i ++ ){
if(a[i] > t[cnt - 1]){
t[cnt ++ ] = a[i];
}
else{
int l = 0, r = cnt - 1;
while(l < r){
int mid = l + r >> 1;
if(t[mid] > a[i]) r = mid - 1;
else l = mid + 1;
}
t[l] = a[i];
}
}
printf("%d", cnt);
return 0;
}
7-2 愿天下有情人都是失散多年的兄妹
五代人需要用追溯,dfs
关于坑点就是对父母的性别,当父母为可考的时候,要赋上性别,为后面追溯同祖先并查集准备。
if (father != -1) a[father].sex = 'M';
if (mother != -1) a[mother].sex = 'F';
还有就是pta上只能c,c的结构体和c++设置有一点点不一样(
#include<stdio.h>
#define max 100000
typedef struct Node{
int father;
int mother;
char sex;
}node;
node a[max];
int n, k;
int pre[max];
int find(int x){
if(x != pre[x]) pre[x] = find(pre[x]);
return pre[x];
}
void Union(int a, int b){
if (b == -1) return ;
int pa = find(a);
int pb = find(b);
if (pa != pb) pre[pa] = pb;
}
int dfs(int x, int y, int age){
if (!(x != -1 && y != -1)) return 1;
if (age > 5) return 1;
if (x == y) return 0;
else
return dfs(a[x].father, a[y].father, age + 1) && dfs(a[x].father, a[y].mother, age + 1) && dfs(a[x].mother, a[y].father, age + 1) && dfs(a[x].mother, a[y].mother, age + 1);
}
int main(){
for (int i = 0; i < max; i++){
pre[i] = i;
a[i].father = -1;
a[i].mother = -1;
}
scanf("%d", &n);
for (int i = 0; i < n; i++){
int id, father, mother;
char sex;
scanf("%d %c %d %d", &id, &sex, &father, &mother);
a[id].father = father;
a[id].sex = sex;
a[id].mother = mother;
Union(id, father);
Union(id, mother);
if (father != -1) a[father].sex = 'M';
if (mother != -1) a[mother].sex = 'F';
}
scanf("%d", &k);
for (int i = 0; i < k; i++){
int x, y;
scanf("%d %d", &x, &y);
if (a[x].sex == a[y].sex) printf("Never Mind\n");
else{
if (find(x) != find(y)) printf("Yes\n");
else if (dfs(x, y, 1)) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
7-3 修理牧场
还不是特别会(
#include<stdio.h>
#include<stdlib.h>
int n;
int a[10010];//原来是一开始开小了,紫砂
int cmp(const void *a, const void *b){
return *(int*)a - *(int*)b;
}
int main(){
int sum = 0, pay = 0, j;
scanf("%d", &n);
for(int i = 0; i < n; i ++ ){
scanf("%d", &a[i]);
}
qsort(a, n, sizeof(a[0]), cmp);
for(int i = 0; i < n - 1; i ++ ){
sum = a[i] + a[i + 1];
pay = pay + sum;
for(j = i + 2; j < n; j ++ ){
if(sum > a[j]) a[j - 1] = a[j];
else{
a[j - 1] = sum;
break;
}
}
if(j == n) a[n - 1] = sum;
}
printf("%d", pay);
return 0;
}
单选题
AOE网络工程最早结束时间
具体解法根据某B求AOE网中的关键路径 数据结构_哔哩哔哩_bilibili的方法解的