pta 郑州轻工业大学2020年数据结构练习集

点击可跳转指定题号

注意: 编程题部分都用的是c++,换一下编译器就行。 直接点击下面对应的题目,后面部分题偷懒把代码放到其他网站了。

写的很烂,龙辉大佬轻点喷QAQ

函数题

6-1 顺序表操作集
6-2 带头结点的链式表操作集
6-3 合并两个有序数组
6-4 线性表元素的区间删除
6-5 递增的整数序列链表的插入
6-6 两个有序链表序列的合并
6-7 求链表的倒数第m个元素
6-8 双端队列
6-9 求二叉树高度
6-10 二叉树的遍历
6-11 二叉树的非递归遍历
6-12 邻接矩阵存储图的深度优先遍历
6-13 邻接表存储图的广度优先遍历
6-14 二叉搜索树的操作集

编程题

7-1 一元多项式的乘法与加法运算
7-2 Reversing Linked List
7-3 符号配对
7-4 表达式转换
7-5 银行业务队列简单模拟
7-6 堆栈模拟队列
7-7 串的模式匹配
7-8 树的同构
7-9 列出叶结点
7-10 修理牧场
7-11 顺序存储的二叉树的最近的公共祖先问题
7-12 列出连通集
7-13 公路村村通
7-14 畅通工程之最低成本建设问题
7-15 最短工期
7-16 哈利·波特的考试
7-17 旅游规划
7-18 六度空间
7-19 是否同一棵二叉搜索树
7-20 电话聊天狂人
7-21 QQ帐户的申请与登陆
7-22 排序
7-23 互评成绩
7-24 人以群分
7-25 寻找大富翁
7-26 PAT排名汇总

6-1 顺序表操作集

/*#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 5
#define ERROR -1
//typedef enum {false, true} bool;
typedef int ElementType;
typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last;
};

List MakeEmpty();
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        if ( Insert(L, X, 0)==false )
            printf(" Insertion Error: %d is not in.\n", X);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else
            printf("%d is at position %d.\n", X, P);
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &P);
        if ( Delete(L, P)==false )
            printf(" Deletion Error.\n");
        if ( Insert(L, 0, P)==false )
            printf(" Insertion Error: 0 is not in.\n");
    }
    return 0;
}*/
List MakeEmpty()
{
    List t;
    t = (List )malloc(sizeof(struct LNode));
    t->Last = -1;
    return t;
}
Position Find( List L, ElementType X )
{
    int i = 0;
    for(int i = 0;i <= L->Last; ++i) if(L->Data[i]==X) return i;
    return ERROR;
}
bool Insert( List L, ElementType X, Position P )
{
    if(L->Last+1==MAXSIZE) {printf("FULL");return false;}
    if(P<0||P>L->Last+1) {printf("ILLEGAL POSITION"); return false;}
    for(int i = L->Last+1; i > P; --i) L->Data[i] = L->Data[i-1];
    L->Data[P] = X; L->Last++;
    return true;
}
bool Delete( List L, Position P )
{
    if(P<0||P>L->Last) {printf("POSITION %d EMPTY", P); return false;}
    for(int i = P; i < L->Last; ++i) L->Data[i] = L->Data[i+1];
    L->Last--;
    return true;
}

6-2 带头结点的链式表操作集

/*#include <stdio.h>
#include <stdlib.h>

#define ERROR NULL
#define gg printf("------");
//typedef enum {false, true} bool;
typedef int ElementType;
typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;

List MakeEmpty();
Position Find( List L, ElementType X );
bool Insert( List L, ElementType X, Position P );
bool Delete( List L, Position P );

int main()
{
    List L;
    ElementType X;
    Position P;
    int N;
    bool flag;

    L = MakeEmpty();
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        flag = Insert(L, X, L->Next);
        if ( flag==false ) printf("Wrong Answer\n");
    }
    scanf("%d", &N);
    while ( N-- ) {
        scanf("%d", &X);
        P = Find(L, X);
        if ( P == ERROR )
            printf("Finding Error: %d is not in.\n", X);
        else {
            flag = Delete(L, P);
            printf("%d is found and deleted.\n", X);
            if ( flag==false )
                printf("Wrong Answer.\n");
        }
    }
    flag = Insert(L, X, NULL);
    if ( flag==false ) printf("Wrong Answer\n");
    else
        printf("%d is inserted as the last element.\n", X);
    P = (Position)malloc(sizeof(struct LNode));
    flag = Insert(L, X, P);
    if ( flag==true ) printf("Wrong Answer\n");
    flag = Delete(L, P);
    if ( flag==true ) printf("Wrong Answer\n");
    for ( P=L->Next; P; P = P->Next ) printf("%d ", P->Data);
    return 0;
}*/
List MakeEmpty()
{
    List t = (List)malloc(sizeof(List));
    t->Data = 0;
    t->Next = NULL;
    return t;
}
Position Find( List L, ElementType X )
{
    L = L->Next;
    while(L&&L->Data!=X) L = L->Next;
    return L;
}
bool Insert( List L, ElementType X, Position P )
{
    List i = L, t = (List)malloc(sizeof(List));
    while(i&&i->Next!=P) i = i->Next;
    if(!i) {puts("Wrong Position for Insertion"); return false;}
    t->Data = X;i->Next = t;
    t->Next = P;
    return true;
}
bool Delete( List L, Position P )
{
    List i = L;
    while(i&&i->Next!=P) i = i->Next;
    if(!i||!P) {puts("Wrong Position for Deletion"); return false;}
    i->Next = P->Next;free(P);
    return true;
}

6-3 合并两个有序数组

/*#include <stdio.h>
#include <stdlib.h>

void printArray(int* arr, int arr_size);
void merge(int* a, int m, int* b, int n, int* c);

int main(int argc, char const *argv[])
{
    int m, n, i;
    int *a, *b, *c;

    scanf("%d", &m);
    a = (int*)malloc(m * sizeof(int));
    for (i = 0; i < m; i++) {
        scanf("%d", &a[i]);
    }

    scanf("%d", &n);
    b = (int*)malloc(n * sizeof(int));
    for (i = 0; i < n; i++) {
        scanf("%d", &b[i]);
    }
    c = (int*)malloc((m + n) * sizeof(int));
    merge(a, m, b, n, c);
    printArray(c, m + n);

    return 0;
}
void printArray(int* arr, int arr_size)
{
    for(int i = 0; i < arr_size; ++i) printf("%d%c", arr[i],i==arr_size-1?'\n':' ');
}*/
void merge(int* a, int m, int* b, int n, int* c)
{
    int cnt = 0, i = 0, j = 0;
    while(i<m&&j<n) c[cnt++] = (a[i]<=b[j])?a[i++]:b[j++];
    for(; i < m; ++i) c[cnt++] = a[i];
    for(; j < n; ++j) c[cnt++] = b[j];
}

6-4 线性表元素的区间删除

/*#include <stdio.h>
#include<stdlib.h>

#define MAXSIZE 20
typedef int ElementType;

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last;
};

List ReadInput();
void PrintList( List L );
List Delete( List L, ElementType minD, ElementType maxD );

int main()
{
    List L;
    ElementType minD, maxD;
    int i;

    L = ReadInput();
    scanf("%d %d", &minD, &maxD);
    L = Delete( L, minD, maxD );
    PrintList( L );

    return 0;
}

List ReadInput()
{
    List head = (List )malloc(sizeof(struct LNode));
    head->Last = -1;
    int n;scanf("%d", &n);
    while(n--) {
        scanf("%d", &head->Data[++head->Last]);
    }
    return head;
}
void PrintList( List L )
{
    for(int i = 0; i <= L->Last; ++i) printf("%d ", L->Data[i]);
}*/
List Delete( List L, ElementType minD, ElementType maxD )
{
    List t = (List )malloc(sizeof(struct LNode));
    t->Last = -1;
    for(int i = 0; i <= L->Last; ++i) {
        int x = L->Data[i];
        if(x>minD&&x<maxD);
        else t->Data[++(t->Last)] = x;
    }
    return t;
}

6-5 递增的整数序列链表的插入

/*#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read();
void Print( List L );

List Insert( List L, ElementType X );

int main()
{
    List L;
    ElementType X;
    L = Read();
    scanf("%d", &X);
    L = Insert(L, X);
    Print(L);
    return 0;
}
List Read()
{
    List head = (List )malloc(sizeof(List)), L;
    head->Next = NULL;
    L = head;
    int n;scanf("%d", &n);
    while(n--) {
        List temp = (List )malloc(sizeof(List));
        scanf("%d", &temp->Data);
        L->Next = temp;
        L = temp;
    }
    L->Next = NULL;
    return head;
}
void Print( List L )
{
    L = L->Next;
    while(L)
    {
        printf("%d ", L->Data);
        L = L->Next;
    }
}
*/
List Insert( List L, ElementType X )
{
    List dis = (List )malloc(sizeof(List));
    List head = L->Next;
    while(head)
    {
        int x = head->Data;
        if(x>=X) {break;}
        head = head->Next;
    }
    if(head == NULL) {
        head = L;
        dis->Data = X;
        while(head->Next!=NULL)
        {
            head = head->Next;
        }
        head->Next = dis; dis->Next = NULL;
    }
    else {
        dis->Data = head->Data;
        dis->Next = head->Next;
        head->Data = X;
        head->Next = dis;
    }
    return L;
}

6-6 两个有序链表序列的合并

/*#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read();
void Print( List L );

List Merge( List L1, List L2 );

int main()
{
    List L1, L2, L;
    L1 = Read();
    L2 = Read();
    L = Merge(L1, L2);
    Print(L);
    Print(L1);
    Print(L2);
    return 0;
}
List Read()
{
    List t = (List )malloc(sizeof(List)), temp, x;
    t->Next = NULL;
    temp = t;
    int n;scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        x = (List)malloc(sizeof(List));
        scanf("%d", &x->Data);
        temp->Next = x;
        temp = x;
    }
    temp->Next = NULL;
    return t;
}
void Print( List L )
{
    L = L->Next;
    if(!L) {puts("NULL"); return;}
    while(L)
    {
        printf("%d ", L->Data);
        L = L->Next;
    }
    printf("\n");
}
*/
List Merge( List L1, List L2 )
{
    List i = L1->Next, j = L2->Next;
    List L = (List)malloc(sizeof(List)), t = L;
    while(i&&j)
    {
        if(i->Data <= j->Data) {
            t->Next = i;
            t = i;
            i = i->Next;
        }
        else {
            t->Next = j;
            t = j;
            j = j->Next;
        }
    }
    t->Next = i?i:j;
    L1->Next = L2->Next = NULL;
    return L;
}

6-7 求链表的倒数第m个元素

/*#include <stdio.h>
#include <stdlib.h>

#define ERROR -1

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read();
void Print( List L );

ElementType Find( List L, int m );

int main()
{
    List L;
    int m;
    L = Read();
    scanf("%d", &m);
    printf("%d\n", Find(L,m));
    Print(L);
    return 0;
}

List Read()
{
    int n;scanf("%d", &n);
    List head = (List)malloc(sizeof(List)), t = head, x;
    while(n--)
    {
        x = (List)malloc(sizeof(List));
        scanf("%d", &x->Data);
        t->Next = x;
        t = x;
    }
    t->Next = NULL;
    return head;
}
void Print( List L )
{
    L = L->Next;
    while(L)
    {
        printf("%d ", L->Data); L = L->Next;
    }
    printf("\n");
}
*/
ElementType Find( List L, int m )
{
    List t = L; int len = 0;
    t = L->Next;
    while(t) {len++; t = t->Next;}
    if(m<=0||m>len) return ERROR;
    len = len-m;
    t = L->Next;
    while(len--)   t = t->Next;
    return t->Data;
}

6-8 双端队列

/*#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, inject, eject, end } Operation;
//typedef enum { false, true } bool;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
    ElementType *Data;      // 存储元素的数组  
    Position Front, Rear;   // 队列的头、尾指针 
    int MaxSize;            // 队列最大容量     
};
typedef PtrToQNode Deque;

Deque CreateDeque( int MaxSize )
{   // 注意:为区分空队列和满队列,需要多开辟一个空间 
    Deque D = (Deque)malloc(sizeof(struct QNode));
    MaxSize++;
    D->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    D->Front = D->Rear = 0;
    D->MaxSize = MaxSize;
    return D;
}

bool Push( ElementType X, Deque D );
ElementType Pop( Deque D );
bool Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

Operation GetOp();
void PrintDeque( Deque D );

int main()
{
    ElementType X;
    Deque D;
    int N, done = 0;

    scanf("%d", &N);
    D = CreateDeque(N);
    while (!done) {
        switch(GetOp()) {
        case push:
            scanf("%d", &X);
            if (!Push(X, D)) printf("Deque is Full!\n");
            break;
        case pop:
            X = Pop(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            else printf("%d is out\n", X);
            break;
        case inject:
            scanf("%d", &X);
            if (!Inject(X, D)) printf("Deque is Full!\n");
            break;
        case eject:
            X = Eject(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            else printf("%d is out\n", X);
            break;
        case end:
            PrintDeque(D);
            done = 1;
            break;
        default:
            break;
        }
    }
    return 0;
}

Operation GetOp()
{
    char s[10];
    scanf(" %s", s);
    if(!strcmp(s, "Push")) return push;
    if(!strcmp(s, "Pop")) return pop;
    if(!strcmp(s, "Inject")) return inject;
    if(!strcmp(s, "Eject")) return eject;
    return end;
}
void PrintDeque( Deque D )
{
    while(D->Front != D->Rear) {
        printf("%d ", D->Data[D->Front]);
        D->Front = (D->Front+1)%D->MaxSize;
    }
    puts("");
}
*/
bool Push( ElementType X, Deque D )
{
    if((D->Rear+1)%D->MaxSize == D->Front) return false;
    D->Front = (D->Front-1+D->MaxSize)%D->MaxSize;
    D->Data[D->Front] = X;
    return true;
}
ElementType Pop( Deque D )
{
    if(D->Front == D->Rear) return ERROR;
    int temp = D->Data[D->Front];
    D->Front = (D->Front+1)%D->MaxSize;
    return temp;
}
bool Inject( ElementType X, Deque D )
{
    if((D->Rear+1)%D->MaxSize == D->Front) return false;
    D->Data[D->Rear] = X;
    D->Rear = (D->Rear+1)%D->MaxSize;
    return true;
}
ElementType Eject( Deque D )
{
    if(D->Front == D->Rear) return ERROR;
    D->Rear = (D->Rear-1+D->MaxSize)%D->MaxSize;
    return D->Data[D->Rear];
}

6-9 求二叉树高度

//递归左右子树的最大高度加1
int GetHeight(BinTree BT)
{
    if(!BT) return 0;
    int ans = 0;
    if(BT->Left)  ans = GetHeight(BT->Left);
    if(BT->Right&&GetHeight(BT->Right)>ans)  
        ans = GetHeight(BT->Right);
    return ans+1;
}

6-10 二叉树的遍历

//仔细观察一下前三个函数,其实可以这样记住,每一个都是1(遍历左)2(遍历右)3,遍历的区别就是输出的位置在1,2,3那个位置
//位置在1就是前序,2是中序,3是后序,层次遍历稍微复杂一点,要用队列去维护每一层
void InorderTraversal( BinTree BT )//中序
{
    if(!BT)  return ;
    InorderTraversal(BT->Left);
    printf(" %c", BT->Data);
    InorderTraversal(BT->Right);
}
void PreorderTraversal( BinTree BT ) //前序
{
    if(!BT) return ;
    printf(" %c", BT->Data);
    PreorderTraversal(BT->Left);
    PreorderTraversal(BT->Right);
}
void PostorderTraversal( BinTree BT ) //后序
{
    if(!BT) return ;
    PostorderTraversal(BT->Left);
    PostorderTraversal(BT->Right);
    printf(" %c", BT->Data);
}
void LevelorderTraversal( BinTree BT ) //层次
{
    if(!BT) return ;
    BinTree que[1000]; //自己写一个队列
    int head = 0, tail = 0, q_siz = 1000;
    que[tail++] = BT;
    while(head!=tail) {
        BinTree x = que[head];
        head = (head+1)%q_siz;
        printf(" %c", x->Data);
        if(x->Left) que[tail++] = x->Left;
        tail %= q_siz;
        if(x->Right) que[tail++] = x->Right;
        tail %= q_siz;
    }
}

6-11 二叉树的非递归遍历

比递归更复杂,难理解一些,特别是后序遍历,要不是看到上面有个flag和peek函数,估计也不是很好写

void InorderTraversal( BinTree BT )//中序
{
    //先把结点压入,遍历左子树,左子树遍历到底就可以直接弹出访问,然后判断有无右子树,这个时候左子树和根节点都已经输出了
    Stack s = CreateStack();
    while(BT||!IsEmpty(s)){
        while(BT){
            Push(s, BT);
            BT = BT->Left;
        }
        if(!IsEmpty(s)) {
            BT = Pop(s);
            printf(" %c", BT->Data);
            BT = BT->Right;
        }
    }
}
void PreorderTraversal( BinTree BT )//前序
{
    //压入栈的顺序就是根左右,直接压入时输出就行
    Stack s = CreateStack();
    while(BT||!IsEmpty(s)){
        while(BT){
            Push(s, BT);
            printf(" %c", BT->Data);
            BT = BT->Left;
        }
        if(!IsEmpty(s)){ 
            BT = Pop(s);
            BT = BT->Right;
        }
    }
}
void PostorderTraversal( BinTree BT )//后序
{
    Stack s = CreateStack();
    while(BT||!IsEmpty(s)){
        while(BT){
            Push(s, BT);
            BT = BT->Left;
        }
        if(!IsEmpty(s)){
            BT = Peek(s); //先不要删除 
            if(!BT->flag) { //记录这个点有没有走过,避免一直在走一个点,来过直接输出,否则标记并遍历右子树
                BT->flag = 1;
                BT = BT->Right;
            }
            else {
                BT = Pop(s);
                printf(" %c", BT->Data);
                BT = NULL;
            }
        }
    }
}

6-12 邻接矩阵存储图的深度优先遍历

void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) )
{
    Visited[V] = 1;
    Visit(V);
    for(int i = 0; i < Graph->Nv; ++i) {
        int w = Graph->G[V][i];
        if(Visited[i]||w>=INFINITY) continue;//把遍历过的点或者v与i之间不相连的点跳过
        DFS(Graph, i, Visit);
    }
}

6-13 邻接表存储图的广度优先遍历

//简单的问题复杂化,这个写法真的服气。
void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) )
{
    int q[1000], head, tail;
    head = tail = 0;
    q[tail] = S;
    tail = (tail+1)%1000;
    Visited[S] = 1;
    while(head!=tail)
    {
        int u = q[head];
        head = (head+1)%1000;//出队
        Visit(u);
        PtrToAdjVNode tmp = Graph->G[u].FirstEdge;
        
        while(tmp) {
            int v = tmp->AdjV;
            if(!Visited[v]) {
                Visited[v] = 1;
                q[tail] = v;
                tail = (tail+1)%1000;//入队
            }
            tmp = tmp->Next;
        }
    }
}

7-1 一元多项式的乘法与加法运算

#include<bits/stdc++.h>

using namespace std;
const int N = 1e4+10;
int a[N], b[N], c[N];
int main()
{
    int n, m, u, v;
    scanf("%d", &n);
    for(int i = 0;i < n;++i) {
        scanf("%d%d", &u, &v);
        a[v+1000] += u;
    }
    scanf("%d", &m);
    for(int i = 0;i < m;++i) {
        scanf("%d%d", &u, &v);
        b[v+1000] += u;
    }

    for(int i = 0;i <= 2000; ++i)
    for(int j = 0; j <= 2000; ++j) {
        if(a[i]&&b[j]) c[i+j] += a[i]*b[j];
    }
    int f = 0;
    for(int i = 4000; i >= 0; --i) {
        if(c[i]) {
            if(f) printf(" ");
            f = 1, printf("%d %d", c[i], i-2000);
        }
    }
    f ? puts("") : puts("0 0");
    f = 0;
    for(int i = 2000; i >= 0; --i) {
        if(a[i]+b[i])  {
            if(f) printf(" ");
            f = 1, printf("%d %d", a[i]+b[i], i-1000);
        }
    }
    f ? puts("") : puts("0 0");
    return 0;
}

7-2 Reversing Linked List

#include<bits/stdc++.h>

using namespace std;
const int N = 1e5+10;
struct node
{
    int Address, Data, Next;
}a[N];
vector<node> ans;
int main()
{
    int head,n,k;
    scanf("%d%d%d", &head, &n, &k);
    for(int i = 0; i < n; ++i) {
        int u, v, w;scanf("%d%d%d", &u, &v, &w);
        a[u].Address = u, a[u].Data = v, a[u].Next = w;
    }
    while(head!=-1) {ans.push_back(a[head]); head = a[head].Next;}
    n = ans.size();
    for(int i = 0; i+k-1 < n; i+=k) reverse(ans.begin()+i, ans.begin()+i+k);
    for(int i = 0; i < n; ++i) {
        printf("%05d %d ", ans[i].Address, ans[i].Data);
        (i == n-1) ? printf("-1\n") : printf("%05d\n", ans[i+1].Address);
    }
    return 0;
}

7-3 符号配对

#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
using namespace std;
string s, t;
stack<int> stk;
bool ok()
{
    if(stk.empty())    return false;
    else if(stk.top()==1) cout<<"NO\n/*-?";
    else if(stk.top()==2) cout<<"NO\n(-?";
    else if(stk.top()==3) cout<<"NO\n[-?";
    else if(stk.top()==4) cout<<"NO\n{-?";
    return true;
}
void solve()
{
    int n = s.size();
    for(int i = 0; i < n; ++i) {
        char x = s[i];
        //if(i==11) debug(stk.top());
        switch(x)
        {
            case '/':
                if(i+1<n&&s[i+1]=='*') stk.push(1), i++; break;
            case '(':
                stk.push(2); break;
            case '[':
                stk.push(3); break;
            case '{':
                stk.push(4); break;
            case '*':
                if(i+1<n&&s[i+1]=='/') {if(!stk.empty()&&stk.top() == 1) i++,stk.pop();else {if(ok()); else cout<<"NO\n?-*/"; return ;}}
                break;
            case ')':
                if(!stk.empty()&&stk.top()==2) stk.pop();else {if(ok()); else cout<<"NO\n?-)";return ;} break;
            case ']':
                if(!stk.empty()&&stk.top()==3) stk.pop();else {if(ok()); else cout<<"NO\n?-]";return ;} break;
            case '}':
                if(!stk.empty()&&stk.top()==4) stk.pop();else {if(ok()); else cout<<"NO\n?-}";return ;} break;
            default : break;
        }
    }
    //cout<<"....";
    if(stk.empty())    cout<<"YES\n";
    else if(stk.top()==1) cout<<"NO\n/*-?";
    else if(stk.top()==2) cout<<"NO\n(-?";
    else if(stk.top()==3) cout<<"NO\n[-?";
    else if(stk.top()==4) cout<<"NO\n{-?";
}
int main()
{

    //cin.ignore();
    while(1)
    {
        cin>>t;
        //debug(t);
        if(t[0]=='.') break;
        s += t;
    }
    solve();
    return 0;
}
// {/*/} .
// (/*/) .

7-4 表达式转换

这题给我整吐了,还有小数点和正负号,正号不用输出,题目啥也没说,不过提交的错误里说明了,还是怪我没仔细看。
#include<bits/stdc++.h>

#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define nl cout<<endl;
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;

stack<char> stk;
string s;
int f;
void ok()
{
    if(f) cout<<" ";
    f++;
}
void solve()
{
    int n = s.size();
    for(int i = 0; i < n; ++i) {
        if((i<1||s[i-1]=='(')&&(s[i]=='+'||s[i]=='-')||s[i]=='.'||isdigit(s[i])) {
                ok();
                if(s[i]!='+') cout<<s[i];
                while(i+1<n&&(s[i+1]=='.'||isdigit(s[i+1]))) cout<<s[++i];
        }
        else {
            char x = s[i];
            if(stk.empty()||x=='(') stk.push(x);
            else if(x == ')') {while(stk.top()!='(') {char temp = stk.top(); cout<<" "<<temp; stk.pop();} stk.pop();}
            else if(x=='+'||x=='-') {
                while(!stk.empty()&&stk.top()!='(') {
                        char temp = stk.top();stk.pop();
                        cout<<" "<<temp;
                }
                stk.push(x);
            }
            else if(x=='*'||x=='/') {
                while(!stk.empty()&&(stk.top()=='*'||stk.top()=='/')) {
                    char temp = stk.top();stk.pop();
                    ok();cout<<temp;
                }
                stk.push(x);
            }
        }
    }
    while(!stk.empty()) {
        char temp = stk.top();stk.pop();
        cout<<" "<<temp;
    }
}
int main()
{
    //int t;scanf("%d", &t);while(t--)
    cin>>s;
        solve();
    return 0;
}



7-5 银行业务队列简单模拟

#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
using namespace std;
const int N = 1e5+10;
queue<int> stka, stkb;
int a[N];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
    int c = 0;
    for(int i = 0; i < n; ++i) {
        if(a[i]%2==1) stka.push(a[i]);
        else stkb.push(a[i]);

    }
    int f = 0;
    while(!stka.empty()||!stkb.empty())
    {
        for(int i = 0; i < 2; ++i)
        if(!stka.empty()) {if(f) printf(" "); f++; printf("%d", stka.front());stka.pop();}

        if(!stkb.empty()) {if(f) printf(" "); f++; printf("%d", stkb.front());stkb.pop();}
    }
    return 0;
}


7-6 堆栈模拟队列

用两个栈来模拟队列,主要思路就是利用两个栈对数据进行处理。其中一个栈作为中转栈,另一个作为输出栈,也就是出队。通过手动模拟很容易发现只有把中转栈的元素按栈的方式提出并放入另一个栈中才是队列的方式。且当输出栈还有元素时,是不能再往里面加元素的,且中转栈的数据个数不能大于输出栈。也就是说两个栈都只能用到最小的那个的大小。然后就可以进行模拟队列了。

#include<bits/stdc++.h>

#define debug(x) cout <<#x<<" = "<<x<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define nl cout<<endl;
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
stack<int> s1, s2;
int n, m;
void solve()
{
    char s;
    int x;
    n = min(n, m);
    while(scanf(" %c", &s), s!='T')
    {
        if(s=='D'){
            if(s1.empty()&&s2.empty()) puts("ERROR:Empty");
            else {
                if(!s2.empty()) printf("%d\n", s2.top()), s2.pop();
                else {
                    int t = s1.size();
                    while(t--) {
                        s2.push(s1.top());
                        s1.pop();
                    }
                    printf("%d\n", s2.top()); s2.pop();
                }
            }
        }
        else {
            scanf("%d", &x);
            if(s1.size()==n&&s2.empty()) {
                int t = min(n, (int)s1.size());
                    while(t--) {
                        s2.push(s1.top());
                        s1.pop();
                    }
            }
            if(s1.size()>=n){puts("ERROR:Full");}
            else s1.push(x);
        }
    }
}
int main()
{
    //int t;scanf("%d", &t);while(t--)
    scanf("%d%d", &n, &m);
    solve();
    return 0;
}



7-7 串的模式匹配

#include<bits/stdc++.h>

#define pb push_back
#define inf 0x3f3f3f3f
#define debug(x) cout <<#x<<" = "<<x<<endl
using namespace std;
const int N = 1e6+10;
typedef long long ll;

int Next[N];
char ori[N], pat[N];
void get_next()
{
    int i = 0, j = -1;
    Next[0] = -1;
    while(pat[i]) {
        if(j==-1||pat[i]==pat[j]) Next[++i] = ++j;
        else j = Next[j];
    }
}
int kmp()
{
    get_next();
    int ans = 0;
    int i = 0, j = 0;
    while(ori[i]) {
        if(j == -1||ori[i]==pat[j]) ++i, ++j;
        else j = Next[j];
        if(j!=-1&&!pat[j]) return i;
    }
    return -1;
}
void solve()
{
    scanf(" %s", pat);
    int t = kmp();
    //debug(t);
    if(t == -1) puts("Not Found");
    else {
        printf("%s", pat);
        for(int i = t; ori[i]; ++i) putchar(ori[i]);
        puts("");
    }
}
int main()
{
    scanf(" %s", ori);
    int t;scanf("%d", &t);while(t--)
        solve();
	return 0;
}

7-8 树的同构

#include<bits/stdc++.h>

using namespace std;
const int N = 1e3+10;

struct node
{
    char a;
    int b, c;
}T1[N], T2[N];
int work(char x) {return x=='-'?-1:x-'0';}
bool pan(int l, int r)
{
    char s1, s2, t1, t2;
    if(T1[l].b==-1) s1='$';
    else s1 = T1[T1[l].b].a;
    if(T1[l].c==-1) s2='$';
    else s2 = T1[T1[l].c].a;

    if(T2[r].b==-1) t1='$';
    else t1 = T2[T2[r].b].a;
    if(T2[r].c==-1) t2='$';
    else t2 = T2[T2[r].c].a;
    return ((s1==t1&&s2==t2)||(s1==t2&&s2==t1)) ;
}
int main()
{
    //暴力乱写,就是找到相同的节点然后判断左右节点是否相同,可以反过来,注意可能没有相同的节点,这样直接就输出No就行。
    int n, m;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
        char b, c;scanf(" %c %c %c", &T1[i].a, &b, &c);
        T1[i].b = work(b); T1[i].c = work(c);
    }
    scanf("%d", &m);
    for(int i = 0; i < m; ++i) {
        char b, c;scanf(" %c %c %c", &T2[i].a, &b, &c);
        T2[i].b = work(b); T2[i].c = work(c);
    }
    if(n!=m) {puts("No"); return 0;}
    for(int i = 0; i < n; ++i) {
        int j = 0;
        for(;j < m; ++j) {
            if(T1[i].a == T2[j].a) {
                if(!pan(i, j)){puts("No"); return 0;}
                break;
            }
        }
        if(j==m) {puts("No"); return 0;}
    }
    puts("Yes");
    return 0;
}

7-9 列出叶结点

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include<vector>
#include<queue>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define debug2(x, y) cout<<x<<" "<<y<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define SZ(x) (int)x.size()
#define se second
#define pb push_back
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef pair<pii, ll> Pii;
template<class T> inline void read(T &x){
    x=0; char c=getchar(); int f=1;
    while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
    while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 2666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
const ll mod = (ll(1)<<47);

int f[N], n, l[N], r[N];
int Find(int x){return f[x] = (x==f[x])?x:Find(f[x]);}
int work(char x)
{
    return x=='-'?-1:x-'0';
}
int flag = 0;
void dfs(int x)
{
    queue<int> q;
    q.push(x);
    while(!q.empty()){
        int u = q.front();q.pop();
        int ul = l[u], ur = r[u];
        if(ul+ur==-2) {
            if(flag++!=0) printf(" ");
            printf("%d", u);
        }
        if(ul != -1) q.push(ul);
        if(ur != -1) q.push(ur);
    }
}
void solve()
{
    ///主要就是利用并查集找到根节点,然后用个队列实现层序遍历,判断一下,注意末尾无空格。
    scanf("%d", &n);
    char u, v;
    for(int i = 0; i <= n; ++i) f[i] = i;
    for(int i = 0; i < n; ++i) {
        scanf(" %c %c", &u, &v);
        int hu = work(u), hv = work(v);
        if(hu!=-1) f[hu] = Find(i);
        if(hv!=-1) f[hv] = Find(i);
        l[i] = hu, r[i] = hv;
    }
    int root = Find(0);
   // printf("%d---\n", root);
    dfs(root);
}
int main()
{
    //int t;scanf("%d", &t);while(t--)
    //while(~scanf("%d%d", &n, &m))
    solve();
	return 0;
}

7-10 修理牧场

#include<bits/stdc++.h>

using namespace std;
const int N = 1e4+10;
typedef long long ll;
int a[N], n;
int main()
{
    //一段木头被截次数乘以其长度的和就是总的花费,那么就用优先队列实现让短的部分被截次数多,长的少。
    //写完看了别人的博客发现这不就是哈夫曼树吗,就是用优先队列来优化
    //优先队列,就是自动排序的队列,这个是升序,把greater改成less就是降序
    priority_queue<int, vector<int>, greater<int> > q;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for(int i = 0; i < n; ++i) q.push(a[i]);
    ll ans = 0;
    while(q.size()>1) {
        int l = q.top();q.pop();
        int r = q.top();q.pop();
        ans += (l+r);
        q.push(l+r);
    }
    printf("%lld\n", ans);
    return 0;
}

7-11 顺序存储的二叉树的最近的公共祖先问题

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include<vector>
#include<queue>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define debug2(x, y) cout<<x<<" "<<y<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define SZ(x) (int)x.size()
#define se second
#define pb push_back
#define inf 0x3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef pair<pii, ll> Pii;
template<class T> inline void read(T &x){
    x=0; char c=getchar(); int f=1;
    while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
    while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 2666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
const ll mod = (ll(1)<<47);

vector<int> G[N];
int T[N], n;
int DEG = 20;
int fa[N][20], deg[N];
void build(int rt)
{
    int l = rt<<1, r = rt<<1|1;
    if(l<=n&&T[l]) G[rt].pb(l), build(l);
    if(r<=n&&T[r]) G[rt].pb(r), build(r);
}
void bfs(int root)
{
    queue<int> q;
    deg[root] = 0;
    fa[root][0] = root;
    q.push(root);
    while(!q.empty()){
        int u = q.front();q.pop();
        for(int i = 1;i < DEG; ++i)
            fa[u][i] = fa[fa[u][i-1]][i-1];
        for(int i = 0; i < SZ(G[u]); ++i) {
            int v = G[u][i];
            if(v == fa[u][0]) continue;
            deg[v] = deg[u]+1;
            fa[v][0] = u;
            q.push(v);
        }
    }
}
int lca(int u, int v)
{
    if(deg[u]>deg[v]) swap(u, v);
    int hu = deg[u], hv = deg[v];
    int tu = u, tv = v;
    for(int det = hv-hu, i = 0; det; det>>=1, ++i)
        if(det&1) tv = fa[tv][i];
    if(tv == tu) return tu;
    for(int i = DEG-1; i>=0; --i) {
        if(fa[tu][i] == fa[tv][i]) continue;
        tu = fa[tu][i];
        tv = fa[tv][i];
    }
    return fa[tu][0];
}
void solve()
{
    ///管他三七二十一,建树,套lca模板美滋滋
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) scanf("%d", &T[i]);
    build(1);
    bfs(1);
    int u, v;scanf("%d%d", &u, &v);
    if(!T[u]) {
        printf("ERROR: T[%d] is NULL\n", u);
        return ;
    }
    if(!T[v]) {
        printf("ERROR: T[%d] is NULL\n", v);
        return ;
    }
    int dis = lca(u, v);
    printf("%d %d\n", dis, T[dis]);
}
int main()
{
    //int t;scanf("%d", &t);while(t--)
    //while(~scanf("%d%d", &n, &m))
    solve();
	return 0;
}

7-12 列出连通集

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include<vector>
#include<queue>
#include<bits/stdc++.h>
#define debug(x) cout <<#x<<" = "<<x<<endl
#define debug2(x, y) cout<<x<<" "<<y<<endl
#define gg cout <<"---------------QAQ---------------"<<endl
#define fi first
#define SZ(x) (int)x.size()
#define se second
#define pb push_back
#define inf 0x3f3f3f3f3f3f3f3f
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef pair<pii, ll> Pii;
template<class T> inline void read(T &x){
    x=0; char c=getchar(); int f=1;
    while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
    while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
const int N = 366666, maxn = 1666666;
void FAST(){ios::sync_with_stdio(false);cin.tie(0);}
const ll mod = 1e9+7;

int n, m;
vector<int> G[N];
bool vis[100];
void dfs(int u)
{
    vis[u] = 1;
    printf(" %d", u);
    for(int i = 0; i < SZ(G[u]); ++i)
    {
        int v = G[u][i];
        if(vis[v]) continue;
        vis[v] = 1;
        dfs(v);
    }
}
void bfs(int u)
{
    queue<int> q;
    q.push(u);
    vis[u] = 1;
    while(!q.empty()) {
        int t = q.front(); q.pop();
        printf(" %d", t);
        for(int i = 0; i < SZ(G[t]); ++i){
            int v = G[t][i];
            if(vis[v]) continue;
            q.push(v);
            vis[v] = 1;
        }
    }
}
void solve()
{
    scanf("%d%d", &n, &m);
    while(m--) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].pb(v);
        G[v].pb(u);
    }
    //细节排序,排完序就是按递增
    for(int i = 0; i < n; ++i) sort(G[i].begin(), G[i].end());
    memset(vis, 0, sizeof(vis));
    for(int i = 0; i < n; ++i) {
        if(vis[i]) continue;
        printf("{");dfs(i);printf(" }\n");
    }
    memset(vis, 0, sizeof(vis));
    for(int i = 0; i < n; ++i) {
        if(vis[i]) continue;
        printf("{");bfs(i);printf(" }\n");
    }
}
int main()
{

//    int _;scanf("%d", &_);while(_--)
//    while(~scanf("%d%d", &n, &m))
    solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44070289/article/details/104517309
今日推荐