2021SCAU数据结构复习 实验六 (各种排序算法)-实验7

题1:8638 直接插入排序

题目描述

Description
用函数实现直接插入排序,并输出每趟排序的结果.

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出一趟排序结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
4 5 8 0 9 3 2 6 7 1
4 5 8 0 9 3 2 6 7 1
0 4 5 8 9 3 2 6 7 1
0 4 5 8 9 3 2 6 7 1
0 3 4 5 8 9 2 6 7 1
0 2 3 4 5 8 9 6 7 1
0 2 3 4 5 6 8 9 7 1
0 2 3 4 5 6 7 8 9 1
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

每步都将一个待排序的对象,按其关键码的大小,插入到前面已经排好序的一组对象的适当位置上,直到对象全部插入到正确的位置。
也就是边插入边排序。
具体过程:起初,a[0]是长度为1的子序列,然后逐一将a[1]到a[n-1]插入到有序子序列中。
在插入a[i]之前, 数组a的前半段(a[0]-a[i-1])是有序段,而后半段仅仅只是含有输入次序关系的无序段
插入a[i]使得a[0]-a[i]这一段都要是有序的,也就是要为a[i]找到有序位置j,那么j的范围也就是有序段中的任意一个位置,也就是在(0-i),注意,也有可能在最后插入的,所以要搞清楚遍历元素的范围。
插入位置的确定:首先要找到,他在有序段中,他比前一个的要大,他比后一个的要小,这个位置就是他的位置,假如从头找到尾都没有找到比他小的数,也就是j到i了,这时候直接插入到尾部即可。
所以一共分为三种情况:(1)插入到中间,这是最普遍的情况(2)插入到最前面。(3)插入到最后面。
插入排序的种类有三种:顺序法定位插入位置:这种排序方法就是直接插入排序。
二分法:二分插入排序
缩小增量,多遍插入排序:希尔排序
那么做插入排序的基本步骤就是:定位插入位置,将需要搬动元素整体向后移动。直到所有元素都定位到正确的位置为止。

AC代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
int *a,n;
void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void InsertSort()
{
    int i,j;
    for(i=2;i<=n;i++)
    {
        a[0]=a[i];
        for(j=i-1;a[0]<a[j];j--)//如果说当前遍历的元素比哨兵元素仍然要大的时候就要向前走
        {
            a[j+1]=a[j];
        }
        a[j+1]=a[0];
        Print();
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    a=new int[n+5];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    InsertSort();
}

题2:8639 折半插入排序

题目描述

Description
用函数实现折半插入排序,并输出每趟排序的结果.

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出一趟排序结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
4 5 8 0 9 3 2 6 7 1
4 5 8 0 9 3 2 6 7 1
0 4 5 8 9 3 2 6 7 1
0 4 5 8 9 3 2 6 7 1
0 3 4 5 8 9 2 6 7 1
0 2 3 4 5 8 9 6 7 1
0 2 3 4 5 6 8 9 7 1
0 2 3 4 5 6 7 8 9 1
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

排序的基本思路仍然是插入排序,但是可以通过折半二分的方式来提高找到插入的概率和效率。
那么是什么原理呢?在上面已经说到,正确的插入位置应当是左边比他小,右边比他大,那么在这个查找的过程中,是在有序段查找的,这正好符合我们二分查找的思路,所以就可以在查找的这个过程中加入二分的算法,来提高我们的算法效率。

AC代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
int *a,n;
void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void InsertSort()
{
    int i,j;
    for(i=2;i<=n;i++)
    {
        a[0]=a[i];
        /*在这里改动*/
        int l=1,r=i-1,mid=(l+r)/2;/*int运算,自动向下取整,不担心*/
        while(l<=r)
        {
            mid=(l+r)/2;//要找的是比a[0]小的元素
            if(a[0]<a[mid])
            {
                r=mid-1;/*假如在有序区,待插入的元素比中间元素小,那么就可以锁定a[0]应当放在左边那个区间*/
            }
            else
            {
                l=mid+1;/*假如在有序区,待插入的元素比中间元素大,那么就可以锁定a[0]应当放在右边那个区间*/
            }
        }//当就是说,待插入的元素已经实现一个比左边大,比右边小的时候,就会不断触发这两个条件中的其中一个,最终导致r<l,就跳出循环了,具体的过程可以画个图看一下,最后插入位置应当是r+1
        //找到插入位置后进入搬动元素
        for(j=i-1;j>=r+1;j--)
        {
            a[j+1]=a[j];
        }
        a[j+1]=a[0];
        Print();
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    a=new int[n+5];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    InsertSort();
}

题3:8640 希尔(shell)排序

题目描述

Description
用函数实现希尔(shell)排序,并输出每趟排序的结果,初始增量d=n/2,其后d=d/2

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出一趟排序结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
3 2 6 0 1 5 4 8 7 9
1 0 3 2 4 5 6 8 7 9
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

缩小增量,多遍插入排序:希尔排序。
原本的直接插入排序就是比较一次,指针只移动一位,而希尔排序的话就是比较一次,指针移动若干位,这个位,我们称为增量。
具体步骤:先将整个待排序记录序列分割位若干个子序列,分别进行直接插入排序,待整个序列中的记录”基本有序“时,再对全体记录进行一次直接插入排序。注意:增量是会逐渐递减的,直到最后做成一个1的直接插入排序,注意,增量序列应当是互质的.

AC代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void InsertSort()
{
    int t,k,i;
    for(t=n/2;t>0;t/=2)
    {
        for(i=t;i<=n;i++)
        {
            a[0]=a[i];
            for(k=i-t; k>=0 && a[k]>a[0];k-=t)
            {
                a[k+t]=a[k];
            }
            a[k+t]=a[0];
        }
        Print();
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    InsertSort();
    return 0;
}

题4:8641 冒泡排序

题目描述

Description
用函数实现冒泡排序,并输出每趟排序的结果(要求当一趟冒泡过程中不再有数据交换,则排序结束)

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出每趟排序结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
4 5 0 8 3 2 6 7 1 9
4 0 5 3 2 6 7 1 8 9
0 4 3 2 5 6 1 7 8 9
0 3 2 4 5 1 6 7 8 9
0 2 3 4 1 5 6 7 8 9
0 2 3 1 4 5 6 7 8 9
0 2 1 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

冒泡排序属于交换排序的范畴,也就是遍历数组,当遇到逆序的时候就完成一次交换,直到遍历数组时没有再存在逆序的情况为止。
那么冒泡排序的基本思想就是:每趟不断将记录两两比较,并按照前小后大的给规则交换。

AC代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void SwapSort()
{
    int i,j;
    for(i=1;i<=n-1;i++)
    {
        bool t=false;
        for(j=1;j<n;j++)
        {
            if(a[j]>a[j+1])
            {
                t=true;
                swap(a[j],a[j+1]);
            }
        }
        Print();
        if(!t)
        {
            break;
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    SwapSort();
    return 0;
}

题5:8642 快速排序

题目描述

Description
用函数实现快速排序,并输出每次分区后排序的结果

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出每趟排序的结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
1 4 2 0 3 5 9 6 7 8
0 1 2 4 3 5 9 6 7 8
0 1 2 4 3 5 9 6 7 8
0 1 2 3 4 5 9 6 7 8
0 1 2 3 4 5 8 6 7 9
0 1 2 3 4 5 7 6 8 9
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

任取一个元素(如第一个)为中心
所有比他小的元素一律向前放,比他大的元素一律向后放,从而形成左右两个子表,然后再对各子表进行重选中心元素,然后依此规则进行调整,算法的出口是当子表中只剩下一个元素了(因为一个元素总是有序的)
通过一趟排序,将待排序的记录分割成独立的两部分,其分割出来的两个部分记录的关键字中,左边的均比右边的要小,然后通过分治的方法来进行排序,从而达到排序的效果。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

int pos(int l,int r)
{
    a[0]=a[l];
    while(l<r)
    {
        while(l<r && a[r]>=a[0])
        {
            r--;
        }
        a[l]=a[r];
        while(l<r && a[l]<=a[0])
        {
            l++;
        }
        a[r]=a[l];
    }
    a[l]=a[0];
    Print();
    return l;
}

void Sort(int l,int r)
{
    if(l<r)
    {
        int mid=pos(l,r);
        Sort(l,mid-1);
        Sort(mid+1,r);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    Sort(1,n);
    return 0;
}

题6:8643 简单选择排序

题目描述

Description
用函数实现简单选择排序,并输出每趟排序的结果

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出每趟排序的结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
0 4 8 5 9 3 2 6 7 1
0 1 8 5 9 3 2 6 7 4
0 1 2 5 9 3 8 6 7 4
0 1 2 3 9 5 8 6 7 4
0 1 2 3 4 5 8 6 7 9
0 1 2 3 4 5 8 6 7 9
0 1 2 3 4 5 6 8 7 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

在待排序的数据中选出最大(或者最小)的元素放在其最终的位置,这个排序算法与冒泡排序很像,但是是有目的性的,冒泡排序是1-n随机元素放在属于自己的位置,而简单插入排序则是按照关键字的大小来确定谁先进行排序,谁后进行排序。

AC代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void SwapSort()
{
    int i,j,t;
    for(i=1;i<n;i++)
    {
        t=i;
        for(j=i+1;j<=n;j++)
        {
            if(a[j]<a[t])
            {
                t=j;
            }
        }
        swap(a[i],a[t]);
        Print();
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    SwapSort();
    return 0;
}

题7:8644 堆排序

题目描述

Description
用函数实现堆排序,并输出每趟排序的结果

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
第一行:初始建堆后的结果
其后各行输出交换堆顶元素并调整堆的结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
9 7 8 6 4 3 2 5 0 1
8 7 3 6 4 1 2 5 0 9
7 6 3 5 4 1 2 0 8 9
6 5 3 0 4 1 2 7 8 9
5 4 3 0 2 1 6 7 8 9
4 2 3 0 1 5 6 7 8 9
3 2 1 0 4 5 6 7 8 9
2 0 1 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

堆的定义,若n个元素的序列a1,a2…an都满足有
ai<=a2i && ai<=a2i+1的话,这个堆称为小根堆
ai>=a2i && a>=a2i+1的话,这个堆称为大根堆
那么从数据结构的角度上来看,堆实际上就是满足以下性质的完全二叉树:二叉树中任一非叶子节点均小于(大于)它的孩子节点
那么在这两种堆中,根据以上的性质,就可以知道,大根堆的堆顶,就是最大值,小根堆的堆顶,就是最小值。
那么在输出堆顶的最小值(最大值)后,使得剩余n-1个元素的序列重又建成一个堆,则得到n个元素的次最小值,或者得到次最大值,如此反复,就能够得到一个有序序列,那么这个过程就称为堆排序。
需要解决两个问题:
①如何由一个无序序列建成一个堆?
②如何在输出堆顶元素后,把剩下的元素调整为一个新的堆?
对于小根堆而言:
①输出堆顶元素之后,以堆中最后一个元素替代之
②然后将根节点值与左、右子数的根节点值进行比较,并与其中小者进行交换
③重复上述操作,直至叶子节点,将得到新的堆。
关键步骤:取原堆中的最后一个元素,将其置于堆顶,比较其左右孩子的大小,并与其中较小值交换。
重要公式,计算一个数组下标所对应的父节点和左右子节点
假设当前需要heapify的数组节点下标是i,那么他的父节点的下标就是(i-1)/2,则其左右子节点的下标分别是2i+1,2i+2;
注意int除法的自动向下取整的功能,所以不需要担心

AC代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=0;i<n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void Heapift(int idx,int cnt)
{
    if(idx>=cnt)
    {
        return ;
    }
    int c1=2*idx+1;
    int c2=2*idx+2;
    int Max=idx;
    if(c1<cnt && a[Max]<a[c1])
    {
        Max=c1;
    }
    if(c2<cnt && a[Max]<a[c2])
    {
        Max=c2;
    }
    if(Max!=idx)
    {
        swap(a[idx],a[Max]);
        Heapift(Max,cnt);
    }

}

void BuiltHeap()
{
    int leaf=n-1;
    int p=(leaf-1)/2;
    for(int i=p;i>=0;i--)
    {
        Heapift(i,n);
    }
    Print();
}

void HeapSort()
{
    BuiltHeap();
    int i;
    for(i=n-1;i>0;i--)
    {
        swap(a[i],a[0]);
        Heapift(0,i);
        Print();
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    HeapSort();
    return 0;
}

题8:8645 归并排序(非递归算法)

题目描述

Description
用函数实现归并排序(非递归算法),并输出每趟排序的结果

输入格式
第一行:键盘输入待排序关键的个数n
第二行:输入n个待排序关键字,用空格分隔数据

输出格式
每行输出每趟排序的结果,数据之间用一个空格分隔

输入样例
10
5 4 8 0 9 3 2 6 7 1

输出样例
4 5 0 8 3 9 2 6 1 7
0 4 5 8 2 3 6 9 1 7
0 2 3 4 5 6 8 9 1 7
0 1 2 3 4 5 6 7 8 9

提示

作者 yqm

排序基本思想

归并排序的操作是建立在归并操作上的一种有效的算法,归并排序对序列元素进行逐层折半分组,然后从最小分组开始比较,合并成一个大的数组,逐层进行,最终所有的元素都是有序的。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int M=1e5+5;
int a[M],n;

void Print()
{
    for(int i=1;i<=n;i++)
    {
        cout<<a[i]<<" ";
    }
    cout<<endl;
}

void Merge(int num[],int l,int mid,int r)
{
    int *tmp=new int[r-l];
    int i=l,j=mid,k=0;
    while(i<mid && j<r)
    {
        if(num[i]>num[j])
        {
            tmp[k++]=num[j++];
            continue;
        }
        tmp[k++]=num[i++];
    }
    while(i<mid)
    {
        tmp[k++]=num[i++];
    }
    while(j<r)
    {
        tmp[k++]=num[j++];
    }
    for(int i=0;i<k;i++)
    {
        num[l++]=tmp[i];
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int wid=1;
    for(wid=1;wid<n;wid*=2)
    {
        int bg=1,ed,mid;
        for(bg=1;bg<=n;bg+=wid*2)
        {
            mid=bg+wid;
            ed=bg+2*wid;
            if(mid>n)
            {
                mid=n+1;
            }
            if(ed>n)
            {
                ed=n+1;
            }
            Merge(a,bg,mid,ed);
        }
        Print();
    }

}

题1:8647 实现图的存储结构

题目描述

Description
实现有向图的邻接矩阵存储结构。

输入格式
第一行:输入图的顶点个数n(各个顶点的默认编号为1~n), 边的条数m。
第二 ~ m+1行:每行输入两个顶点编号i、j,表示连接顶点i到顶点j的一条边。

输出格式
分n行输出n*n的邻接矩阵,表示所输入的图存储,顶点i和顶点j之间如果有边相连,则输出1,没边相连则输出0。

输入样例
4 4
1 2
1 3
3 4
4 1

输出样例
0 1 1 0
0 0 0 0
0 0 0 1
1 0 0 0

提示

作者 yqm

AC代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int M=1e3+5;
int a[M][M];

int main()
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int x,y;cin>>x>>y;
        a[x][y]=1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

题2:8648 图的深度遍历

题目描述

Description 实现图的邻接表存储结构及一些基本操作函数。在此基础上实现图的深度遍历算法并加以测试。本题只给出部分代码,请补全内容。输入格式
第一行:输入0到3之间整数(有向图:0,有向网:1,无向图:2,无向网:3);
第二行:输入顶点数和边数;
第三行:输入各个顶点的值(字符型,长度〈3);(遍历从输入的第一个顶点开始)
第四行:输入每条弧(边)弧尾和弧头(以空格作为间隔),如果是网还要输入权值;

输出格式
输出对图深度遍历的结果。

输入样例
0
3 3
a b c
a b
b c
c b

输出样例
a b c

提示
注意题目的邻接表采用的是头插法,也就是后出现的边节点先被访问。

作者 yqm

AC代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int M=1e5+5;
vector <int> e[M];
int book[M];
void dfs(int cur)
{
    cout<<(char)(cur+'a')<<' ';
    int len=e[cur].size();
    for(int i=0;i<len;i++)
    {
        int y=e[cur][i];
        if(book[y]==0)
        {
            book[y]=1;
            dfs(y);
        }
    }
    return ;
}

int main()
{
    ios::sync_with_stdio(false);
    int t;cin>>t;
    int n,m;cin>>n>>m;
    int st;
    for(int i=0;i<n;i++)
    {
        char x;cin>>x;/*cjb*/
    }
    for(int i=0;i<m;i++)
    {
        char x,y;cin>>x>>y;
        int a=(char)(x-'a');
        int b=(char)(y-'a');
        if(i==0)
        {
            st=a;
        }
        if(t<=1)
        {
            e[a].insert(e[a].begin(),b);
        }
        else
        {
            e[a].insert(e[a].begin(),b);
            e[b].insert(e[b].begin(),a);
        }
    }
    book[st]=1;
    dfs(st);
    return 0;
}

题3:8649 图的广度遍历

题目描述

Description
使用图的深度遍历实现的邻接表存储结构和基本操作函数,在此基础上实现图的广度遍历算法并加以测试。注意正确使用队列存储结构。

输入格式
第一行:输入0到3之间整数(有向图:0,有向网:1,无向图:2,无向网:3);
第二行:输入顶点数和边数;
第三行:输入各个顶点的值(字符型,长度〈3);(遍历从输入的第一个顶点开始)
第四行:输入每条弧(边)弧尾和弧头(以空格作为间隔),如果是网还要输入权值;

输出格式
输出对图广度遍历的结果

输入样例
0
3 3
a b c
a b
b c
c b

输出样例
a b c

提示
注意题目的邻接表采用头插法,也就是后出现的边节点插入到邻接表的表头。

作者 yqm

AC代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int M=1e5+5;
vector <int> e[M];
int q[M];
int book[M];
int main()
{
    ios::sync_with_stdio(false);
    int t;cin>>t;
    int n,m;cin>>n>>m;
    int st;
    for(int i=0;i<n;i++)
    {
        char x;cin>>x;/*cjb*/
    }
    for(int i=0;i<m;i++)
    {
        char x,y;cin>>x>>y;
        int a=(char)(x-'a');
        int b=(char)(y-'a');
        if(i==0)
        {
            st=a;
        }
        if(t<=1)
        {
            e[a].insert(e[a].begin(),b);
        }
        else
        {
            e[a].insert(e[a].begin(),b);
            e[b].insert(e[b].begin(),a);
        }
    }
    int head=0,tail=0;
    book[st]=1;
    q[tail++]=st;
    while(head<tail)
    {
        int y=q[head];
        head++;
        int len=e[y].size();
        cout<<(char)(y+'a')<<' ';
        for(int i=0;i<len;i++)
        {
            if(book[e[y][i]]==0)
            {
                book[e[y][i]]=1;
                q[tail++]=e[y][i];
            }
        }
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值