跳转至

2021秋数据结构平时实验题目和参考解答

括号匹配

Description

输入一串字符串,其中有普通的字符与括号组成(包括‘(’、‘)’、‘[’,']'),要求验证括号是否匹配,如果匹配则输出0、否则输出1.

Input 字符串长度<=100

Output 验证括号是否匹配,如果匹配则输出0、否则输出1.

Sample Input 1

dfa(sdf)df[dfds(dfd)] Sample Output 1

0

#include <cstdio>
#include <vector>

using namespace std;

int main()
{
    vector<char> container;
    char c;
    bool flag = true;

    while ((c = getchar()) != EOF)
    {
        // printf("c = %c\n", c);
        if (c == '(')
            container.push_back(')');
        else if (c == '[')
            container.push_back(']');
        else if ((c == ')') || (c == ']'))
        {
            if (container.back() != c)
            {
                flag = false;
                break;
            }
            else
                container.pop_back();
        }
    }
    printf("%d\n", !(flag && container.empty()) );

    return 0;
}

寻找最近的相同字母位置

Description

寻找最近的相同字母位置

Input 输入:第一行输入字母矩阵的大小 m * n.

第二行输入要查找的字母坐标.

之后输入 m * n 个字母.

m < 10, n < 10.

Output 输出: 距离查找字母最近的相同字母坐标.(坐标从(0,0) 开始)

找不到输出-1 -1

Sample Input 1

3 2 1 1 q w a x x a Sample Output 1

2 0

#include <cstdlib>
#include <deque>
#include <iostream>

using namespace std;

struct Point
{
    int x;
    int y;
    char data;
    Point(int x, int y, char data) : x(x), y(y), data(data) {}
};

Point *find_nearest(int src_x, int src_y, char **matrix, int row, int col)
{
    bool visited[row][col] = {0};
    deque<Point *> q;
    char key = matrix[src_x][src_y];
    q.push_back(new Point(src_x, src_y, matrix[src_x][src_y]));

    visited[src_x][src_y] = true;
    while (!q.empty())
    {
        Point *pt = q.front();
        for (int i = pt->x - 1; i <= pt->x + 1; ++i)
        {
            for (int j = pt->y - 1; j <= pt->y + 1; ++j)
            {
                if (!visited[i][j])
                {
                    visited[i][j] = true;
                    if (i != 0 && i != row - 1 && j != 0 && j != col - 1)
                    {
                        char elem = matrix[i][j];
                        Point *ptr_point = new Point(i, j, elem);
                        if (elem == key)
                            // 这里有个问题,deque里面存放的指向堆的指针并没有被释放
                            return ptr_point;
                        q.push_back(ptr_point);
                    }
                }
            }
        }
        delete q.front();
        q.pop_front();
    }
    return NULL;
}

int main()
{
    int row, col, x, y;

    cin >> row >> col;
    char **matrix = (char **)malloc(sizeof(char *) * (row + 2));
    for (int i = 0; i < row + 2; ++i)
        matrix[i] = (char *)calloc(col + 2, sizeof(char));

    cin >> x >> y;

    for (int i = 1; i < row + 1; ++i)
    {
        for (int j = 1; j < col + 1; ++j)
            cin >> matrix[i][j];
    }

    Point *ptr_point = find_nearest(x + 1, y + 1, matrix, row + 2, col + 2);
    if (ptr_point)
        cout << ptr_point->x - 1 << " " << ptr_point->y - 1;
    else
        cout << "-1 -1";

    return 0;
}

LifeGame

题目描述

生命游戏在一个 \(6 \times 6\) 的网格上进行,每个格子有"活"或"死"两种状态。每个格子有 8 个相邻格子(上下左右及对角线)。

演化规则如下:

  • 活细胞:若相邻活细胞数 \(\leq 1\)\(\geq 4\),则死亡;否则存活
  • 死细胞:若相邻活细胞数恰好为 \(3\),则复活;否则保持死亡

给定初始状态和演化次数,求最终状态。

输入

第一行三个整数:演化次数 \(times\),初始活细胞的行号 \(row\),列号 \(col\)

随后若干行,每行两个整数表示一个活细胞的行列坐标,以 -1 -1 结束

数据范围: \(1 \leq times \leq 100\)\(1 \leq row, col \leq 6\)

输出

\(6\) 行,每行 \(6\) 个整数(0 或 1),表示最终状态,整数间空格分隔

样例输入

2 2 2
2 3
3 2
3 3
-1 -1

样例输出

0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0

注:代码中 numOfNeighbor 函数有 bug,循环条件 j <= col - 1 应为 j <= col + 1

#include <cstdio>
#include <cstring>

#define MAXROW 6
#define MAXCOL 6

class Life
{
private:
    bool grid[MAXROW + 2][MAXCOL + 2];

    bool isAlive(int row, int col)
    {
        return grid[row][col];
    }

    void setDeath(int row, int col)
    {
        grid[row][col] = 0;
    }

    int numOfNeighbor(int row, int col)
    {
        int num = 0;
        for (int i = row - 1; i <= row + 1; i++)
        {
            for (int j = col - 1; j <= col - 1; j++)
                num += grid[i][j];
        }
        if (isAlive(row, col))
            num--;
        return num;
    }

public:
    Life()
    {
        memset(grid, 0, sizeof(grid));
    }

    void setAlive(int row, int col)
    {
        grid[row][col] = 1;
    }

    void updateState()
    {
        for (int i = 1; i <= MAXROW; i++)
        {
            for (int j = 1; j <= MAXCOL; j++)
            {
                int num = numOfNeighbor(i, j);
                if (isAlive(i, j))
                {
                    if (num <= 1)
                        setDeath(i, j);
                    else if (num >= 4)
                        setDeath(i, j);
                }
                else if (num == 3)
                    setAlive(i, j);
            }
        }
    }

    void printState()
    {
        for (int i = 1; i <= MAXROW; i++)
        {
            printf("%d", grid[i][1]);
            for (int j = 2; j <= MAXCOL; j++)
                printf(" %d", grid[i][j]);
            printf("\n");
        }

    }
};

int main()
{
    Life l;
    int times, row, col;
    scanf("%d %d %d", &times, &row, &col);
    while ((row != -1) || (col != -1))
    {   
        l.setAlive(row, col);
        scanf("%d %d", &row, &col);
    }

    for (int i = 0; i < times; ++i)
        l.updateState();
    l.printState();

    return 0;
}

合并升序列表

题目描述

给定两个升序排列的单链表,请将它们合并为一个新的升序链表并输出。

新链表由两个链表中的所有节点组成,且保持升序排列。

输入

输入共两行:

  • 第一行:一个正整数 \(m\),表示第一个链表的长度,随后在同一行输入 \(m\) 个升序排列的整数
  • 第二行:一个正整数 \(n\),表示第二个链表的长度,随后在同一行输入 \(n\) 个升序排列的整数

数据范围:

  • \(1 \leq m, n \leq 1000\)
  • \(-10^4 \leq \text{节点值} \leq 10^4\)

输出

输出一行,为合并后的升序链表,各元素之间用空格分隔。

样例输入

4 1 3 5 7
3 2 4 6

样例输出

1 2 3 4 5 6 7

样例解释

将链表 1 → 3 → 5 → 7 与链表 2 → 4 → 6 合并后,得到升序链表 1 → 2 → 3 → 4 → 5 → 6 → 7

#include <iostream>

using namespace std;

struct LinkNode
{
    LinkNode *next;
    int data;
    LinkNode() : next(nullptr) {}
    LinkNode(int x) : next(nullptr), data(x) {}
};

struct List
{
    LinkNode *head;
    LinkNode *tail;
    List()
    {
        LinkNode *dummy_header = new LinkNode();
        head = dummy_header;
        tail = dummy_header;
    }
    void push_back(int x)
    {
        tail->next = new LinkNode(x);
        tail = tail->next;
    }
    void print_list()
    {
        for (auto p = head->next; p != nullptr; p = p->next)
            cout << p->data << " ";
        cout << endl;
    }
    void merge(List l1, List l2)
    {
        LinkNode *p1 = l1.head->next;
        LinkNode *p2 = l2.head->next;
        while ((p1 != nullptr) && (p2 != nullptr))
        {
            if (p1->data < p2->data)
            {
                this->push_back(p1->data);
                p1 = p1->next;
            }
            else
            {
                this->push_back(p2->data);
                p2 = p2->next;
            }
        }
        while (p1 != nullptr)
        {
            this->push_back(p1->data);
            p1 = p1->next;
        }
        while (p2 != nullptr)
        {
            this->push_back(p2->data);
            p2 = p2->next;
        }
    }
};

int main()
{
    List l1, l2, l3;

    int m, n;
    cin >> m;
    for (int i = 0; i < m; ++i)
    {
        int x;
        cin >> x;
        l1.push_back(x);
    }

    cin >> n;
    for (int i = 0; i < n; ++i)
    {
        int x;
        cin >> x;
        l2.push_back(x);
    }

    l3.merge(l1, l2);
    l3.print_list();

    return 0;
}

八皇后问题拓展

如何在N*N的棋盘上放置N枚棋子,使得任意两个棋子不出现在同一直线上?一共有多少种方法

Input

1个整数,放置棋子个数N

Output

1个整数,可能的放置方法个数。

Sample Input 1

8

Sample Output 1

92
#include <iostream>
#include <vector>

using namespace std;
#define MaxSize 32

class Solution
{
public:
    vector<int> place;
    int n;
    int cnt_solution;

    Solution(): cnt_solution(0)
    {
        place.reserve(MaxSize);
    }

    bool able_place(int row, int col)
    {
        for (int i = 0; i < row; ++i)
        {
            if (place[i] == col || abs(place[i] - col) == row - i)
                return false;
        }
        return true;
    }

    void DFS(int row)
    {
        // cout << "row = " << row << endl;
        // for (int i = 0; i < row; ++i)
        //     cout << place[i] << " ";
        // cout << endl;

        if (row == n)
        {
            ++cnt_solution;

            if (cnt_solution <= 3)
            {
                cout << place[0] + 1;
                for (int i = 1; i < row; ++i)
                    cout << " " << place[i] + 1;
                cout << endl;
            }

        }
        else
        {
            for (int col = 0; col < n; ++col)
            {
                if (able_place(row, col))
                {
                    place[row] = col;
                    DFS(row + 1);
                }
            }
        }
    }

    int eight_queen(int n)
    {
        this->n = n;
        DFS(0);
        return cnt_solution;
    }

};

int main()
{
    int n;
    cin >> n;
    cout << Solution().eight_queen(n) << endl;

    return 0;
}

子集合大小

Description

请使用递归的方法,求出n个元素的集合中元素个数为m的子集合个数。

Input

第1行,2个整数,原集合大小n,子集合大小m。

第2行,n个整数,为子集合元素。

Output

输出所有子集合,子集合中元素顺序输出。

Sample Input 1

5 3
1 2 3 4 5

Sample Output 1

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 
#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:
    int n;
    int k;
    int cnt_subset;

    Solution() : cnt_subset(0) {}

    void DFS(int start, int current_sum)
    {
        if (start == n)
        {
            if (current_sum == k)
                ++cnt_subset;
        }
        else
        {
            if (current_sum + 1 <= k)
                DFS(start + 1, current_sum + 1);
            else if (current_sum > k)
                return;
            DFS(start + 1, current_sum);
        }

    }

    int num_subset(int n, int k)
    {
        this->n = n;
        this->k = k;
        DFS(0, 0);
        return cnt_subset;
    }
};

int main()
{
    int n, k;
    cin >> n >> k;

    cout << Solution().num_subset(n, k) << endl;

    return 0;
}

其他题目

1. 单链表的实现

题目描述

实现一个单链表,支持以下操作: - add x:在链表头部插入元素 x - remove x:删除链表中第一个值为 x 的节点 - find x:查找链表中是否存在值为 x 的节点 - clear:清空链表

输入

第一行一个整数 N,表示操作次数。

随后 N 行,每行一个操作命令。

输出

对于每个 find 操作,若找到输出 1,否则输出 0

最后,若链表为空输出 empty linklist,否则输出链表中所有元素(从头到尾)。

样例输入

5 add 3 add 5 find 3 remove 3 find 3

样例输出

1 0 5

代码

#include<iostream>
using namespace std;

struct Node {
    Node *next;
    Node();
    int entry;
    Node(int item, Node *add_on = NULL);
};

Node::Node( )
{
    next = NULL;
}

Node::Node(int item, Node *add_on)
{
    entry = item;
    next = add_on;
}

enum Error_code{overflow,emptylist,notexist,notfound,success};

class LinkList{
    public:
        Error_code add(int &item);
        Error_code remove(int &item);
        Error_code find(int &item);
        Error_code clear();
        int empty();
        void print();
        LinkList();
    private:
    Node *head;
};

LinkList::LinkList()
{
    head=NULL;
}

Error_code LinkList::add(int &item)
{
    Node *new_node = new Node (item, head);
    if(new_node==NULL)return overflow;
    head=new_node;
    return success;
 } 

Error_code LinkList::find(int &item)
{
    if(head==NULL)
    {
        return emptylist;
    }
    Node *cur=head;
    while(cur!=NULL)
    {
        if(cur->entry==item)
        {
            return success;
        }
        cur=cur->next;
    }
    return notexist;
}

Error_code LinkList::remove(int &item)
{
    if(head==NULL)
    {
        return emptylist;
    }
    Node *pre=NULL,*cur=head; 
    while(cur!=NULL)
    {
        if(cur->entry==item)
        {
            if(pre==NULL)
            {
                head=head->next;
            }
            else
            {
                pre->next=cur->next;
            }
            delete cur;
            cur=NULL;
            return success;
        }
        pre=cur;
        cur=cur->next;
    }
    return notexist;
}

Error_code LinkList::clear()
{
    Node *cur=head,*pre=cur;
    while(cur)
    {
        pre=cur;
        cur=cur->next;
        delete pre;
        pre = NULL;
    }
    head=NULL;
}

int LinkList::empty()
{
    if(head==NULL)
    return 1;
    return 0;
}

void LinkList::print()
{
    if(empty())
    {
        return;
    }
    Node *cur= head;
    while(cur->next)
    {
        cout<<cur->entry<<" ";
        cur=cur->next;
    }
    cout<<cur->entry;
}

int main()
{
    int N;
    cin>>N;
    string op;
    int num;
    Error_code err[100];
    int count[100]={0};
    LinkList *ll=new LinkList();
    int i;
    for(i=0;i<N;i++)
    {
        cin>>op;

        if(op=="add")
        {
            cin>>num;
            ll->add(num);
        }
        else if(op=="remove")
        {
            cin>>num;
            ll->remove(num);
        }
        else if(op=="find")
        {
            cin>>num;
            count[i]=1;
            err[i]=ll->find(num);
        }
        else if(op=="clear")
        {
            ll->clear();
        }
    }

    for(i=0;i<N;i++)
    {
        if(count[i]!=0)
        {
           if(err[i]==success)
           {
              cout<<"1"<<endl;
           }
           else 
           {
              cout<<"0"<<endl;
           }            
        }
    }

    if(ll->empty())
    {
        cout<<"empty linklist"<<endl;
    }

    else
    {
        ll->print();
    }
    return 0;
}

2. 岛屿数量

题目描述

给定一个 m × n 的二维网格,网格由 1(陆地)和 0(水)组成。计算网格中岛屿的数量。

岛屿总是被水包围,且每座岛屿只能由水平和垂直方向上相邻的陆地连接形成。

输入

第一行两个整数 m 和 n,表示网格的行数和列数。

随后 m 行,每行 n 个整数(0 或 1),表示网格。

输出

输出一个整数,表示岛屿的数量。

样例输入

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

样例输出

3

代码

#include<bits/stdc++.h>
using namespace std;
struct Islands{
    public:
        Islands(int m,int n);
        int result;
        void dfs(int a[15][15],int x,int y);
        bool isisland(int a[15][15],int x,int y);
        void solve(int a[15][15]);
    private:
        int array[100][100];
        int row;
        int col;
};

Islands::Islands(int m,int n)
{
    row=m;
    col=n;
    result=0;
}

void Islands::solve(int a[15][15])
{
    for(int i=0;i<row;i++)
            for(int j=0;j<col;j++){
                if(a[i][j]==1){
                    result++;
                    dfs(a,i,j);
                }
            }
}

void Islands::dfs(int a[15][15],int x,int y)
{
    a[x][y]=0;
    if(x==row-1&&y==col-1)
    return ;
    if(x-1>=0 && a[x-1][y]==1)
            dfs(a,x-1,y);
    if(x+1<row && a[x+1][y]==1)
            dfs(a,x+1,y);
    if(y-1>=0 && a[x][y-1]==1)
            dfs(a,x,y-1);
    if(y+1<col && a[x][y+1]==1)
            dfs(a,x,y+1);
}

int main()
{
    int m,n;
    cin>>m>>n;

    int array[15][15];
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>array[i][j];
        }
    }
    Islands island(m,n);
    island.solve(array);
    cout<<island.result;
    return 0;
}

3. 高精度乘法

题目描述

给定两个正整数(可能非常大,超出普通整型范围),计算它们的乘积。

输入

两行,每行一个正整数。

输出

输出两个数的乘积。

样例输入

123456789
987654321

样例输出

121932631112635269

代码

#include<bits/stdc++.h>
using namespace std;

struct Node
{
 char Num;
 Node *Prev,*Next;
};

class BigInteger
{
 Node *Head,*End,*TempNode;
 void AddHead(char Num);
 void AddEnd(char Num);
 public:
  BigInteger();
  BigInteger(const BigInteger &BigNum);
  void GetNumber();
  void disp();
  BigInteger operator + (const BigInteger &BigNum);
  BigInteger operator * (const BigInteger &BigNum);
  BigInteger operator = (const BigInteger &BigNum);
  ~BigInteger();
};

BigInteger::BigInteger()
{
 Head=End=TempNode=NULL;
}

BigInteger::BigInteger(const BigInteger &BigNum)
{
 Node *p;
 Head=End=TempNode=NULL;
 p=BigNum.Head;
 while(p)
 {
  AddEnd(p->Num);
  p=p->Next;
 }
}

BigInteger::~BigInteger()
{
 Node *NextNode;
 if(Head==NULL)
  return;
 TempNode=Head;
 while(TempNode)
 {
  NextNode=TempNode->Next;
  delete TempNode;
  TempNode=NextNode;
 }
 Head=NULL;
 End=NULL;
 TempNode=NULL;
}

void BigInteger::AddHead(char Num)
{
 TempNode=new Node;
 TempNode->Num=Num;
 TempNode->Prev=NULL;
 if(!Head)
 {
  Head=End=TempNode;
  TempNode->Next=NULL;
 }
 else
 {
  TempNode->Next=Head;
  Head->Prev=TempNode;
  Head=TempNode;
 }
}

void BigInteger::AddEnd(char Num)
{
 TempNode=new Node;
 TempNode->Num=Num;
 TempNode->Next=NULL;
 if(!Head)
 {
  Head=End=TempNode;
  TempNode->Prev=NULL;
 }
 else
 {
  TempNode->Prev=End;
  End->Next=TempNode;
  End=TempNode;
 }
}

void BigInteger::GetNumber()
{
 char key;
 int count=0,num=0;
 while((key=getchar())!=10)
 {
  if(key>='0' && key<='9')
  {
   num=key-'0';
   AddEnd(num);
   num=0;
  }
 }
}

BigInteger BigInteger::operator + (const BigInteger &BigNum2)
{
 BigInteger &BigNum1=*this,result;
 Node *temp1,*temp2;
 int TempNum,rest=0;
 temp1=BigNum1.End;
 temp2=BigNum2.End;
 while(temp1 && temp2)
 {
  TempNum=int(temp1->Num)+int(temp2->Num)+rest;
  if(TempNum>9)
  {
   TempNum=TempNum-10;
   rest=1;
  }
  else
   rest=0;
  result.AddHead(char(TempNum));
  temp1=temp1->Prev;
  temp2=temp2->Prev;
 }
 if(temp2)temp1=temp2;
 while(temp1)
 {
  int(TempNum)=int(temp1->Num)+rest;
  if(TempNum>9)
  {
   TempNum=TempNum-10;
   rest=1;
  }
  else
   rest=0;
  result.AddHead(char(TempNum));
  temp1=temp1->Prev;
 }
 if(rest)
  result.AddHead(char(rest));
 return result;
}

BigInteger BigInteger::operator * (const BigInteger &BigNum2)
{
 BigInteger &BigNum1=*this,temp,result;
 Node *temp1,*temp2,*tempa,*tempb;
 int TempNum,rest,i=0,rest2;
 temp1=BigNum1.End;
 temp2=BigNum2.End;
 while(temp2)
 {
  rest=0;
  while(temp1!=NULL)
  {
   TempNum=int(temp1->Num)*int(temp2->Num)+rest;
   if(TempNum>9)
   { 
    rest=TempNum/10;
    TempNum=TempNum%10;
   }
   else
    rest=0;
   temp.AddHead(char(TempNum));
   temp1=temp1->Prev;
  }
  if(rest!=0)temp.AddHead(char(rest));
  for(int k=i;k>=1;k--)temp.AddEnd(char(0));
  i++;
  temp1=BigNum1.End;
  temp2=temp2->Prev;
  tempa=result.End;
  if(result.Head!=NULL)
  {
   result.End=temp.Head;
   result.Head=NULL;
  }
  tempb=temp.End;
  rest2=0;
  while(tempa!=NULL && tempb!=NULL)
  {
   TempNum=int(tempa->Num)+int(tempb->Num)+rest2;
   if(TempNum>9)
   {
    TempNum=TempNum-10;
    rest2=1;
   }
   else
    rest2=0;
   result.AddHead(char(TempNum));
   tempa=tempa->Prev;
   tempb=tempb->Prev;
  }
  if(tempb)tempa=tempb;
  while(tempa)
  {
   int(TempNum)=int(tempa->Num)+rest2;
   if(TempNum>9)
   {
    TempNum=TempNum-10;
    rest2=1;
   }
   else
    rest2=0;
   result.AddHead(char(TempNum));
   tempa=tempa->Prev;
  }
  if(rest2)
   result.AddHead(char(rest2));
  if(temp.Head!=NULL)
  {
   temp.End=temp.Head;
   temp.Head=NULL;
  }
  tempb=NULL;
 }
 return result;
}

BigInteger BigInteger::operator = (const BigInteger &BigNum)
{
 if(this==&BigNum)
  return *this;
 Node *p;
 TempNode=Head=End=NULL;
 p=BigNum.Head;
 while(p)
 {
  AddEnd(p->Num);
  p=p->Next;
 }
 return *this;
}

void BigInteger::disp()
{
 if(Head)
 {
  cout<<int(Head->Num);
  TempNode=Head->Next;
 }
 else return;
 while(TempNode)
 {
  cout<<int(TempNode->Num);
  TempNode=TempNode->Next;
 }
 cout<<endl;
}

int main()
{
    BigInteger BigNum1,BigNum2,BigNum3;
    BigNum1.GetNumber();
    BigNum2.GetNumber();
    BigNum3=BigNum1*BigNum2;
    BigNum3.disp();
   return 0;
}

4. 高精度加法

题目描述

给定两个正整数(可能非常大,超出普通整型范围),计算它们的和。

输入

一行,两个正整数,用空格分隔。

输出

输出两个数的和。

样例输入

999999999999999999 1

样例输出

1000000000000000000

代码

#include<bits/stdc++.h> 
using namespace std;
string s1,s2;
int ans[1000010];
int a[1000010],b[1000010];
int main(){
    cin>>s1>>s2;
    int len1=s1.size(),len2=s2.size();
    for(int j=0,i=len1-1;i>=0;i--){
        a[j++]=s1[i]-'0';
    }                           
    for(int j=0,i=len2-1;i>=0;i--){
        b[j++]=s2[i]-'0';
    }
    int carry=0;
    int len=0;
    for(int i=0;i<max(len1,len2);i++){
        int t=a[i]+b[i]+carry;
        ans[len++]=t%10;
        carry=t/10;
    }
    if(carry!=0){
        ans[len++]=carry;
    }
    for(int i=len-1;i>=0;i--){
        cout<<ans[i];
    }                           
    return 0;
}

5. 合并两个升序列表

题目描述

给定两个升序排列的单链表,请将它们合并为一个新的升序链表并输出。

输入

第一行一个整数 N,表示第一个链表的长度,随后在同一行输入 N 个升序排列的整数。

第二行一个整数 M,表示第二个链表的长度,随后在同一行输入 M 个升序排列的整数。

输出

输出合并后的升序链表,各元素之间用空格分隔。

样例输入

4 1 3 5 7
3 2 4 6

样例输出

1 2 3 4 5 6 7

代码

#include<iostream>
using namespace std;

struct Node {
    Node *next;
    Node();
    int entry;
    Node(int item, Node *add_on = NULL);
};

Node::Node( )
{
    next = NULL;
}

Node::Node(int item, Node *add_on)
{
    entry = item;
    next = add_on;
}

enum Error_code{overflow,emptylist,notexist,notfound,success};

class LinkList{
    public:
        Error_code add(int &item);
        Error_code remove(int &item);
        int empty();
        void print();
        LinkList();
        Node *head;
};

LinkList::LinkList()
{
    head=new Node(-1,NULL);
}

Error_code LinkList::add(int &item)
{
    Node *p=head;
    while(p->next!=NULL)
    {
        p=p->next;
     } 
    Node *new_node = new Node (item, NULL);
    p->next=new_node;
    return success;
 }


int LinkList::empty()
{
    if(head==NULL)
    return 1;
    return 0;
}

void LinkList::print()
{
    if(empty())
    {
        return;
    }
    Node *cur= head->next;
    while(cur->next)
    {
        cout<<cur->entry<<" ";
        cur=cur->next;
    }
    cout<<cur->entry;
}


int main()
{
    int N,M;
    cin>>N;
    int number;
    LinkList *L1=new LinkList();
    LinkList *L2=new LinkList();
    LinkList *L3=new LinkList();

    for(int i=0;i<N;i++)
    {
        cin>>number;
        L1->add(number);
    }

    cin>>M;
    for(int i=0;i<M;i++)
    {
        cin>>number;
        L2->add(number);
    }   

    Node *p1=L1->head->next,*p2=L2->head->next;

    while(p1!=NULL&&p2!=NULL)
    {
        Node *pr;
        if(p1->entry>=p2->entry) pr=p2;
        if(p2->entry>p1->entry) pr=p1;

        L3->add(pr->entry);     
        if(pr->entry==p1->entry)
        {
            p1=p1->next;
        }
        else
        {
            p2=p2->next;
        }
    }   

    if(p1==NULL)
    {
        while(p2!=NULL)
        { 
           L3->add(p2->entry);
           p2=p2->next;
        } 
    }   

    if(p2==NULL)
    {
        while(p1!=NULL)
        { 
           L3->add(p1->entry);
           p1=p1->next;
        } 
    }

    L3->print();
    return 0;
}

6. 螺旋方阵

题目描述

输入一个正整数 N,生成一个 N × N 的螺旋方阵。螺旋方阵从左上角开始,按照顺时针螺旋方向依次填入 1 到 N² 的数字。

输入

一个正整数 N(N ≤ 10)。

输出

N 行,每行 N 个整数,表示螺旋方阵,整数间用空格分隔。

样例输入

4

样例输出

1 2 3 4 
12 13 14 5 
11 16 15 6 
10 9 8 7 

代码

#include<stdio.h>
#define SIZE 10
void Helix(int a[][SIZE],int n,int turn)
{
    int i,j;
    static int num=1;
        i=turn;
        for(j=turn;j<n;j++){
            if(a[i][j]==0){
            a[i][j]=num;
            num++;
        }
        }
        j=n-1-turn;
        for(i=turn+1;i<n;i++){
            if(a[i][j]==0){
            a[i][j]=num;
            num++;
        }
        }
        i=n-1-turn;
        for(j=n-2-turn;j>=turn;j--){
            if(a[i][j]==0){
            a[i][j]=num;
            num++;
        }
        }
        j=turn;
        for(i=n-1-turn;i>=turn;i--){
            if(a[i][j]==0){
                a[i][j]=num;
                num++;
            }
        }
        if(num>n*n){
            return;
        }
        turn++;
        Helix(a,n,turn);

}
int main(void)
{
    int N,k,p,cot=0;
    scanf("%d",&N);

    int arr[N][N];
    for(k=0;k<N;k++){
        for(p=0;p<N;p++){
            arr[k][p]=0;
        }
    }
    Helix(arr,N,0);
    for(k=0;k<N;k++){
        cot=0;
        for(p=0;p<N;p++){
            cot++;
            printf("%d",arr[k][p]);
            printf(" ");
            if(cot==N){
                printf("\n");
            }
        }
    }
    return 0;
}

7. 模拟栈

题目描述

实现一个栈,支持以下操作: - push c:将字符 c 压入栈中 - pop:弹出栈顶元素

执行完所有操作后,依次输出栈中剩余的元素(从栈顶到栈底)。

输入

第一行一个整数 k,表示操作次数。

随后 k 行,每行一个操作。

输出

输出栈中剩余的元素,用空格分隔。

样例输入

5
push a
push b
push c
pop
push d

样例输出

d b a 

代码

#include<iostream>
#include<cstring>

enum Error_code{underflow,overflow,success};
const int maxstack = 10;
class MyStack{
    public:
        MyStack();
        bool empty();
        Error_code top(char &item);
        Error_code pop();
        Error_code push(char &item);
    private:
        int count;
        char entry[maxstack];
};

MyStack::MyStack(){
    count=0;
    memset(entry,0,sizeof(entry));
} 

bool MyStack::empty()
{
    bool outcome=true;
    if(count>0)
    {
        outcome=false;
    }
    return outcome;
}

Error_code MyStack::pop(){
    if(count==0){
        return underflow;
    }
    count--;
    return success;
}

Error_code MyStack::top(char &item){
    if(count==0){
        return underflow;
    }
    item = entry[count-1];
    return success;
}

Error_code MyStack::push(char &item){
    if(count>=maxstack){
        return overflow;
    }

    entry[count++]=item;
    return success;
}
using namespace std;
int main(){
    MyStack stack;
    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        string s;
        cin>>s;
        if(s=="push"){
            char c;
            cin>>c;
            stack.push(c);
        }
        else {
            stack.pop();
        }
    }
    char tmp; 
    while(!stack.empty()){
        stack.top(tmp);
        cout<<tmp<<" ";     
        stack.pop();
    }

    return 0;
}

8. 实现队列

题目描述

实现一个循环队列,支持入队操作。队列最大容量为 8。

输入 N 个整数依次入队。若 N > 8,先输出 This queue is overflow!,然后只输出队列中的前 8 个元素;否则输出队列中所有元素。

输入

第一行一个整数 N,随后同一行输入 N 个整数。

输出

队列中的元素,用空格分隔。

样例输入

5 1 2 3 4 5

样例输出

1 2 3 4 5 

代码

#include<bits/stdc++.h>
using namespace std; 
enum  Error_code{underflow, overflow, success};
const int maxqueue = 8;
class CirQueue {
public:
   CirQueue();
   bool empty() ;
   Error_code serve();
   Error_code append(int &item);
   Error_code retrieve(int &item);
   bool full();
   int size() ;
   void clear();
   Error_code serve_and_retrieve(int &item);
private:
   int count;
   int front, rear;
   int entry[maxqueue];
};

CirQueue::CirQueue()
{
   count = 0;
   rear = maxqueue - 1;
   front = 0;
}

bool CirQueue::empty() 
{
   return count == 0;
}

Error_code CirQueue::append(int &item)
{
   if (count >= maxqueue) return overflow;
   count++;
   rear = ((rear + 1) == maxqueue) ? 0 : (rear + 1); 
   entry[rear] = item;
   return success;
}

Error_code CirQueue::serve()
{
   if (count <= 0) return underflow;
   count--;
   front = ((front + 1) == maxqueue) ? 0 : (front + 1);
   return success;
}

Error_code CirQueue::retrieve(int &item) 
{
   if (count <= 0) return underflow;
   item = entry[front];
   return success;
}

int CirQueue::size() 
{
   return count;
}

bool CirQueue::full() 
{
  return count==maxqueue;
}

void CirQueue::clear()
{
   count = 0;
   rear = maxqueue-1;
   front = 0;
}

Error_code CirQueue::serve_and_retrieve(int &item)
{
      if (count <= 0) return underflow;
         item = entry[front];
         count--;
         front = ((front + 1) == maxqueue) ? 0 : (front + 1);
         return success;;
}

int main()
{
    CirQueue C;
    int N;
    cin>>N;
    int j;
    int number;

    for(int i=0;i<N;i++)
    {
        cin>>number;
        C.append(number);   
    }
    if(N>8)
    {
    cout<<"This queue is overflow!"<<endl;  
    while(!C.empty())
    {
        int t;
        C.serve_and_retrieve(t);
        cout<<t;
        j++;
        if(j!=8)
        cout<<" ";
     }  
    }
    else{
    while(!C.empty())
    {
        int t;
        C.serve_and_retrieve(t);
        cout<<t<<" ";
     }      
    }

    return 0;
}

9. 寻找相同的字母位置

题目描述

给定一个 m × n 的字符矩阵,以及矩阵中的一个起始位置 (x, y)。使用广度优先搜索(BFS),找到矩阵中与起始位置字符相同的另一个位置。按照上下左右的顺序搜索。

输入

第一行两个整数 m 和 n,表示矩阵的行数和列数。

第二行两个整数 x 和 y,表示起始位置。

随后 m 行,每行 n 个字符,表示矩阵。

输出

输出找到的相同字符的位置坐标,用空格分隔。若未找到,输出 -1 -1

样例输入

3 4
0 0
a b c d
e a f g
h i j k

样例输出

1 1

代码

#include<bits/stdc++.h>
using namespace std;
const int maxqueue=8;
enum Error_code{overflow,underflow,success};

struct Pos{
    int x;
    int y;
};

class Queue{
    public:
        Queue();
        bool empty();
        Error_code serve();
        Error_code retrieve(Pos &item);
        Error_code append(Pos &item);
        bool full()
        {
            return count==maxqueue;
        }
        Error_code serve_and_retrieve(Pos &item);
    private:
        int count,rear,front;
        Pos entry[maxqueue];
};

Queue::Queue()
{
    count=0;
    front=0;
    rear=maxqueue-1;
    memset(entry,0,sizeof(entry));
}

Error_code Queue::append(Pos &item)
{
    if(count>=maxqueue)
    {
        return overflow;
    }
    else
    {
        count++;
        rear=((rear+1)==maxqueue)? 0:(rear+1);
        entry[rear]=item;
        return success;
    }
}

bool Queue::empty()
{
    return count==0;
}
Error_code Queue::serve()
{
    if(empty())
    return underflow;
    count--;
    front=((front+1)==maxqueue)? 0:(front+1);
    return success;
}

Error_code Queue::serve_and_retrieve(Pos &item)
{
    if(empty())
    return underflow;
    item=entry[front];
    count--;
    front=((front+1)==maxqueue)? 0:(front+1);
    return success; 
}

Error_code Queue::retrieve(Pos &item)
{
    if(empty())
    return underflow;
    item=entry[front];
    count--;
    front=((front+1)==maxqueue)? 0:(front+1);
    return success;
}

const int maxrow=10,maxcol=10;

int main()
{
    char mat[maxrow][maxcol];
    Queue numbers;
    int m,n;
    cin>>m>>n;
    int x,y;
    cin>>x>>y;
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>mat[i][j];
        }
    }
    int mask[maxrow][maxcol];
    memset(mask,0,sizeof(mask));
    char target=mat[x][y];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    mask[x][y]=1;
    Pos res={-1,-1};
    Pos number={x,y};
    numbers.append(number);
    while(!numbers.empty())
    {
        Pos tmp;
        numbers.serve_and_retrieve(tmp);

        if(mat[tmp.x][tmp.y]==target&&!(tmp.x==x&&tmp.y==y))
        {
            res.x=tmp.x;
            res.y=tmp.y;
            break;
        }

        for(int i=0;i<4;i++)
        {
            int new_x=tmp.x+dx[i];
            int new_y=tmp.y+dy[i];
            Pos temp={new_x,new_y};
            if(new_y>=0&&new_x>=0&&new_y<n&&new_x<m&&mask[new_x][new_y]==0)
            {
                numbers.append(temp);
                mask[new_x][new_y]=1;
            }
        }
    }
    cout<<res.x<<" "<<res.y;
    return 0;
 }

10. 字符串出入栈

题目描述

输入 n 个字符,依次压入栈中,然后依次弹出并输出,实现字符的逆序输出。

输入

第一行一个整数 n,表示字符个数。

第二行 n 个字符。

输出

逆序输出这 n 个字符,用空格分隔。

样例输入

5
a b c d e

样例输出

e d c b a 

代码

#include <iostream>
using namespace std;
enum Error_code
{
    underflow,overflow,success
};
const int maxstack=100;
class Mystack
{
    public:
        Mystack();
        bool empty();
        Error_code push(char &item);
        Error_code pop();
        Error_code top(char &item);
    private:
        int count;
        char entry[maxstack];
};
Mystack::Mystack()
{
    count=0;
}
bool Mystack::empty()
{
    bool outcome=true;
    if(count>0)
    {
        outcome=false;
    }
    return outcome;
}
Error_code Mystack::push(char &item)
{
    Error_code outcome=success;
    if(count>=maxstack)
    {
        outcome=overflow;
    }
    else
    {
        entry[count++]=item;
    }
    return outcome;
}
Error_code Mystack::pop()
{
    Error_code outcome=success;
    if(count==0)
    {
        outcome=underflow;
    }
    else
    {
        --count;
    }
    return outcome;
}
Error_code Mystack::top(char &item)
{
    Error_code outcome=success;
    if(count==0)
    {
        outcome=underflow;
    }
    else
    {
        item=entry[count-1];
    }
    return outcome;
}
int main()
{
    int n;
    char item;
    Mystack strings;
    cout << " Type in an integer n followed by n characters." << endl
    << " The characters will be printed in reverse order." << endl;
    cin >> n;
    int i=0;
    for(i=0;i<n;i++)
    {
        cin >> item;
        strings.push(item);
    }
    cout << endl << endl;
    while(!strings.empty())
    {
        strings.top(item);
        cout << item << " ";
        strings.pop();
    }
    cout << endl;
    return 0;
}