Bootstrap

数据结构的拓展习题(含题目,更新中)

抱佛脚还得看我

抱着复习和避免oj网站进不去的目的,

临时兴起汇总一下OJ的拓展习题,可是时间不大够了(明天就考试T.T)

先这样吧,有空在更新(画大饼也得看我)

目录

拓展习题1

字符串去重

Description

输入格式

输出格式

输入样例

输出样例

统计不同数字的个数(升级版)

Description

输入格式

输出格式

输入样例

输出样例

提示

前缀和

Description

输入格式

输出格式

输入样例

输出样例

提示

差值最大

Description

输入格式

输出格式

输入样例

输出样例

最大子段和

Description

输入格式

输出格式

输入样例

输出样例

提示

拓展习题2

后缀表达式

Description

输入格式

输出格式

输入样例

输出样例

出栈序列合法性判定

Description

输入格式

输出格式

输入样例

输出样例

出栈序列

Description

输入格式

输出格式

输入样例

输出样例

平分物品

Description

输入格式

输出格式

输入样例

输出样例

提示

迷宫问题2

Description

输入格式

输出格式

输入样例

输出样例

拓展习题3

最长单词

Description

输入格式

输出格式

输入样例

输出样例

提示

偏爱字母

Description

输入格式

输出格式

输入样例

输出样例

提示

小易爱回文

Description

输入格式

输出格式

输入样例

输出样例

提示

蛇形方阵

Description

输入格式

输出格式

输入样例

输出样例

提示

拓展习题4

计算二叉树的第k层中所有叶子结点的个数

Description

输入格式

输出格式

输入样例

输出样例

二叉树的之字形遍历

Description

输入格式

输出格式

输入样例

输出样例

二叉树的右视图

Description

输入格式

输出格式

输入样例

输出样例

提示

树上摘樱桃

Description

输入格式

输出格式

输入样例

输出样例

提示

二叉树的最长路径

Description

输入格式

输出格式

输入样例

输出样例

提示

测验习题

不同的字符

描述

输入格式

输出格式

输入样例

输出样例

组队

描述

输入格式

输出格式

输入样例

输出样例

小球(树结构)

描述

输入格式

输出格式

输入样例

输出样例

最小的特殊数字

描述

输入格式

输出格式

输入样例

输出样例

提示



拓展习题1

字符串去重

Description

一个完全由小写字母组成的长度为n的字符串,现在要求你去除所有重复的字母,并将剩下的字母按从小到大的次序输出。
如输入baaadccaab,输出abcd。


 

输入格式

第一行一个整数n,表示字符串长度(0<=n<=100000)。
第二行一个字符串。
 

输出格式

去除所有重复的字母,并将剩下的字母按ASCII码从小到大的次序输出。
 

输入样例

10
baaadccaab
 

输出样例

abcd

 代码如下:

#include <iostream>
using namespace std;
int book[30];//标记出现过的字母
char s[100000];
int main()
{
    int n;
    cin>>n;
    cin>>s;
    for(int i=0;i<n;i++)
    {
        book[s[i]-'a']=1;//换为整形,出现过就标记
    }
    for(int i=0;i<26;i++)//从小到大排序
    {
        if(book[i]==1)
            cout<<(char)(i+'a');
    }
}

统计不同数字的个数(升级版)

Description

由键盘输入n个整数,统计不同数字的个数(0<=n<=200000)。

PS:此题目和1040仅数据规模不同。但如果使用如下O(n2)级别的算法必然会超时。
int main()
{
    int a[21],i,c=0,b,j;
    for(i=1;i<=20;i++)
    {
        cin>>b;
        for(j=1;j<=c;j++)
        {
            if(b==a[j])
            {
                break;
            }
        }
        if(j>c)
        {
            a[c+1]=b;
            c++;
        }
    }
    cout<<c;
    return 0;
}


 

输入格式

第一行一个整数n(0<=n<=200000)。
第二行n个整数a1,a2......an,(0<=ai<=200000)。
 

输出格式

仅一行,不同数字的个数。
 

输入样例

20
70  5  14  22  19  2  99  67  13  66  5  93  44  38  22  11  39  22  33  11
 

输出样例

16
 

提示

如何快速判断某个数字是否在之前出现过?
因为题目告知ai的范围,所以可以开一个bool数组记录数字是否出现(C语言用整型数组)。
例如a[1]=35,设定t[a[1]]=1,即t[35]变为1,。
这样当需要“判断某个数字是否在之前出现过”时,利用数组随机访问的特点可以O(1)的时间得到结果。

 代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
long long v[200005]={0};
int main()
{
   ios::sync_with_stdio(false);
   int n,m,ans=0;
   cin>>n;

   for(int i=0;i<n;i++)
   {
       cin>>m;
       if(!v[m])
        ans++;
       v[m]=1;
   }
   cout<<ans;
}

前缀和

Description

前缀和是一种重要的预处理方法,能极大地降低查询序列区间和的时间复杂度。
现在一个序列中有n个整数,下标从1....n。
有m个查询,每个查询给出一个区间的左右端点下标,请输出这个区间所有数据的和。

注意当题目输入输出数据量比较大时,用cin和cout速度会比较慢,容易超时。解决方法:
(1)用scanf和printf替换
(2)main函数第一条语句加上std::ios::sync_with_stdio(false); 关闭同步会使cin cout速度加快。


 

输入格式

第一行一个整数n。(1<=n<=100000)
第二行n个整数,用空格分隔,int范围。
第三行一个整数m。(1<=m<=100000)
下面m行每行两个整数L,R。(1<=L<=R<=n)
 

输出格式

输出共m行,每行一个整数为对应区间[L,R]的序列和。
注意序列和的数据范围可能超出int范围。
 

输入样例

5
3 -8 4 5 1 
4
3 3
1 1
2 4
1 3
 

输出样例

4
3
1
-1
 

提示

在读入数据后,用一个sum数组来记录从第1个元素到第i个元素的和,for(i=1;i<=n;i++)  sum[i]=sum[i-1]+a[i];
这样区间[L,R]的和可以用sum[R]-sum[L-1]得到。

 代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
long long a[100000],sum[100000]={0};
int main()
{
   ios::sync_with_stdio(false);
   int n,m,l,r;
   cin>>n;
   for(int i=1;i<=n;i++)
   {
       cin>>a[i];
       sum[i]=sum[i-1]+a[i];
   }
   cin>>m;
   while(m--)
   {
       cin>>l>>r;
       cout<<sum[r]-sum[l-1]<<endl;
   }
}

差值最大

Description

一个长度为N的整数序列,找出两个数x和y使x-y的值最大。
要求在序列中x必须在y的右侧。


 

输入格式

第一行是一个正整数N,表示了序列的长度(0<=N<=200000)。
第二行包含N个绝对值不大于10000的整数ai。
 

输出格式

一个整数,为最大的差值。数据确保结果在类型int范围内。
 

输入样例

7
4 -4 3 -1 2 -4 3
 

输出样例

7

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

int main()
{
   int n,y=0,maxn=0;
   cin>>n;
   for(int i=0;i<n;i++)
   {
       int a;
       cin>>a;
       maxn=max(maxn,a-y);//减去数值最小的数,找到最大差值
       y=min(y,a);//y在左侧
   }
   cout<<maxn;
}

最大子段和

Description

一个整数序列,选出其中连续且非空的一段使得这段和最大。
注意当题目要求输入输出的数据量很大时,尽量使用scanf和printf。 c++提供的cin和cout速度比较慢,有可能在读取数据和输出数据时导致超时。

 

输入格式

第一行是一个正整数N,表示了序列的长度(0=<N<=200000)。
第二行包含N个绝对值不大于10000的整数ai。
 

输出格式

一个整数,为最大的子段和。子段的最小长度为1。数据确保结果在类型int范围内。
 

输入样例

7
2 -4 3 -1 2 -4 3
 

输出样例

4
 

提示

【样例说明】
2,-4,3,-1,2,-4,3中,最大的子段和为4,该子段为第三元素至第五元素,即3,-1,2。
#include <iostream>
#include <algorithm>
using namespace std;
int maxn=-200000,n,minn=200000;
int main()
{
     scanf("%d",&n);
    int a[n],s[n]={0};
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        s[i]=s[i-1]+a[i];
    }
    for(int i=1;i<=n;i++)
    {
        minn=min(minn,s[i]);
        maxn=max(maxn,s[i]-minn);//最大子段和为前缀和-最小前缀和
    }
    printf("%d",maxn);
    return 0;
   cout<<maxn;
}

拓展习题2

后缀表达式

Description

人最熟悉的是中缀表达式,但计算机比较难处理中缀表达式,所以往往将中缀表达式改为后缀表达式。 
后缀表达式,又称逆波兰式。现在从键盘读入一个后缀表达式,只含有0-9组成的运算数及加(+)、减(—)、乘(*)、除(/)四种运算符。
每个运算数之间用一个空格隔开,题目所使用的运算数均小于10,并确保所给的表达式合法。以@作为结束标志。


 

输入格式

一个后缀表达式。
 

输出格式

表达式结果。
 

输入样例

6 9 4 3 +*-@
 

输出样例

-57

#include<iostream>
#include<stack>
using namespace std;
int main()
{
    stack<int>S;//定义一个栈
    int a,b,c,ch;
    while((ch=getchar())!='@')//输入数据
    {
        if(ch<='9'&&ch>='0')//挑出数字
        S.push(ch-48);//字符型变整型并入栈
        else if(ch!=' ')
        {
            a=S.top();//存起来方便计算
            S.pop();
            b=S.top();
            S.pop();
            switch(ch)//符号的判断
            {
                case '+':c=a+b;break;
                case '-':c=b-a;break;//注意进出栈的顺序(a和b)
                case '*':c=a*b;break;
                case '/':c=b/a;break;//注意进出栈的顺序(a和b)
                default :break;
            }
            S.push(c);//存入栈中
        }
    }
    cout<<S.top();//做完计算后输出
}

出栈序列合法性判定

Description

每年期末考试必考题目。

一个栈的进栈序列是a、b、c、d、e,则可能的出栈序列是(  )。

A.abecd         B.decba         C.dceab        D.cabde

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。

假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,

但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)


 

输入格式

第一行一个整数n,表示输入序列的长度。(1<=n<=10000)

第二行n个整数,表示栈的压入顺序。

第三行n个整数,表示栈的出栈顺序。
 

输出格式

如果是弹出序列,输出yes,否则输出no。
 

输入样例

5
1 2 3 8 6
8 6 3 2 1
 

输出样例

yes

出栈序列

Description

一种简洁的栈定义方法如下
int st[1000],top=0;//以top作为栈顶指针,top==0为空栈
st[top++]=x;//把x入栈,栈顶指针+1
top--;//出栈
现在有一个1-n的排列,入栈序列已知,请给出字典序最大的出栈序列。


 

输入格式

第一行一个整数n。(1<=n<=100)
第二行n个整数,数据确保为1-n的排列。
 

输出格式

输出n个整数,既字典序最大的出栈序列。
 

输入样例

5
1 2 4 5 3
 

输出样例

5 4 3 2 1

这道题小测考过

#include <iostream>
#include <cstring>
#include <stack>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    int st[105],top=0;
    int n,a[105];
    cin>>n;
    for(int j=0;j<n;j++)
    {
        cin>>a[j];
    }
    int i=0,ma,k;
    while(i<n||top!=0)
    {
        if(top==0)//栈空先入栈
        {
            st[top++]=a[i++];
        }
        else
        {
            ma=st[top-1];//取栈顶
            k=0;
            for(int j=i;j<n;j++)
            {
                if(a[j]>ma)//看后面是否要出栈,此时字典序大
                {
                    ma=a[j];//ma记录最大的数
                    k=j;
                }
            }
            if(k!=0)//如果还没入栈的数比栈顶更大,则更新栈
            {
                for(int j=i;j<=k;j++)
                {
                    st[top++]=a[j];//最大值及其前面的数一个个进栈,为了输出最大字典数
                }
                i=k+1;//更新i,可判断是否还有数没进来
            }
            cout<<st[--top]<<" ";
        }

    }



    return 0;
}

平分物品

Description

网易2021校招笔试-文本挖掘算法工程师(提前批)第一题

现在有n个物品,每一个物品都有一个价值,现在想将这些物品分给两个人,
要求这两个人每一个人分到的物品的价值总和相同(个数可以不同,总价值相同即可,
剩下的物品就需要扔掉,现在想知道最少需要扔多少价值的物品才能满足要求分给两个人。

要求:时间复杂度O(3^n),空间复杂度O(n)






 

输入格式

第一行输入一个整数 T,代表有 T 组测试数据。
对于每一组测试数据,一行输入一个整数 n ,代表物品的个数。
接下来 n 个数,a[i] 代表每一个物品的价值。
1<= T <= 10
1 <= n <= 15
1 <= a[i] <= 100000
 

输出格式

对于每一组测试数据,输出一个答案代表最少需要扔的价值。
多组数据需要换行。


样例解释,扔掉第三个和第四个物品,然后将第一个物品和第五个物品给第一个人,
第二个物品给第二个人,每一个人分到的价值为60,扔掉的价值为20。
 

输入样例

1
5
30 60 5 15 30
 

输出样例

20
 

提示

注意观察题目要求,估算出需要使用何种复杂度算法。
此题目n很小,用3的n次幂这种指数级复杂度可解,可使用基于指数型枚举的深度搜索dfs。
枚举时每个物品都有三种选择,给A,给B,都不给

迷宫问题2

Description

迷宫是一个n*m的矩阵,玩家需要迷宫入口(坐标1,1)出发,寻找路径走到出口(n,m)。
请判断玩家能否从迷宫中走出,如果能走出迷宫输出,输出最短的路径长度,否则输出-1。

正在上传…重新上传取消



 

输入格式

第一行两个整数n和m,代表n行m列。(1<=n,m<=10)
下面n行每行m个字符,0代表可以通行,1代表不可以通行。
 

输出格式

如果能从迷宫走出,输出最短的路径长度,否则输出-1。
 

输入样例

8 8
00100010
00100010
00001100
01110000
00010000
01000100
01110110
00001000
 

输出样例

16

拓展习题3

最长单词

Description

一个以‘.’结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式。


 

输入格式

一个以‘.’结尾的简单英文句子(长度不超过500),单词之间用空格分隔,没有缩写形式和其它特殊形式。
 

输出格式

该句子中最长的单词。如果多于一个,则输出第一个。
 

输入样例

I am a student of Peking University.
 

输出样例

University
 

提示

注意字符"."不属于单词。

偏爱字母

Description

美团2021校招笔试-编程题(通用编程试题,第8场) 

小美喜欢字母E,讨厌字母F。在小美生日时,小团送了小美一个仅包含字母E和F的字符串,
小美想从中选出一个包含字母E数量与字母F数量之差最大的子串。

*子串:从字符串前面连续删去若干个字符,从后面连续删去若干个字符剩下的字符串(也可以一个都不删),
例如abcab是fabcab的子串,而不是abcad的子串。

我们将空串看作所有字符串的子串。


 

输入格式

第一行一个正整数n表示字符串的长度。

第二行长度为n,且仅包含大写字母’E’,’F’的字符串(不含引号)
 

输出格式

输出一个整数,表示最大的差值
 

输入样例

5
EFEEF
 

输出样例

2
 

提示

解题建议:转化数据形式,把E看成1,把F看成-1。算法复杂度为O(n)。

小易爱回文

Description

网易2021校招笔试-音频算法工程师(提前批) 

小易得到了一个仅包含大小写英文字符的字符串,该字符串可能不是回文串。

(“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串,“asds”就不是回文串。)

小易可以在字符串尾部加入任意数量的任意字符,使其字符串变成回文串。

现在请你编写一个程序,程序要能计算出小易可以得到的最短回文串。



 

输入格式

一行包括一个字符串S。S的长度小于1000。
 

输出格式

一行包括一个字符串,代表答案。
 

输入样例

noo
 

输出样例

noon
 

提示

注意回文串的长度可以是奇数,也可以是偶数。
拓展思考:如果长度达到100000,这个题目又该怎么处理呢?

蛇形方阵

Description

给出一个不大于 9 的正整数 n,输出 n×n 的蛇形方阵。

从左上角填上 1 开始,顺时针方向依次填入数字。

如同样例所示。注意每个数字有都会占用 3 个字符,前面使用空格补齐。


 

输入格式

一个整数n。
 

输出格式

n对应的蛇形方阵。
 

输入样例

4
 

输出样例

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

提示

注意输出格式!

拓展习题4

计算二叉树的第k层中所有叶子结点的个数

Description

二叉链表表示的二叉树:按先序次序输入二叉树中结点的值,'#'字符表示空树,构造二叉链表表示的二叉树T(该二叉树中的结点为单个字符并且无值重复的结点),
编写算法完成:计算二叉树的第k层中所有叶子结点个数,根结点为第1层,根结点的孩子结点为第2层,依次类推。
#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int  Status;

typedef char  ElemType;
typedef struct BiTNode{
  ElemType data;
  struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

Status CreateBiTree(BiTree &T) {  // 算法6.4
  // 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
  // 构造二叉链表表示的二叉树T。
  char ch;
  scanf("%c",&ch);
  if (ch=='#') T = NULL;
  else {
    if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
    ________________________ // 生成根结点
     _______________________   // 构造左子树
    _________________________  // 构造右子树
  }
  return OK;
} // CreateBiTree


int main()   //主函数
{
                      //补充代码
 }//main



 

输入格式

第一行输入先序次序二叉树中结点
第二行输入层次k
 

输出格式

第一行输出该二叉树的第k层中所有叶子结点个数
 

输入样例

ABC###D##
2
 

输出样例

1

二叉树的之字形遍历

Description

题目来源:字节跳动测试题

给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
例如:
给定的二叉树是{3,9,20,15,7,#,#},

该二叉树之字形层序遍历的结果是
3
20 9
15 7

正在上传…重新上传取消



 

输入格式

一行字符串,只包含大写字母和#。
此处采用完全二叉树的顺序存储结构。
 

输出格式

若干行,之字形输出树的结点,每一行输出树的一层。
 

输入样例

ABC###D##
 

输出样例

A
C B
D

二叉树的右视图

Description

字节跳动2021面试题

给定一个二叉树的根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
比如此树
   1            <---
 /   \
2     3         <---
 \     
  5             <---
从右侧看过去,答案是1,3,5。
实际上右视图就是二叉树层次遍历时每一层最右侧节点序列。


#include <stdio.h>
#include <malloc.h>
typedef long long ll;
using namespace std;
typedef struct BiTNode
{
    char data;
    struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;
void  CreateBiTree(BiTree &T)
{ /**< 先序建树算法 */
    char ch;
    scanf("%c",&ch);
    if (ch=='#') T = NULL;
    else
    {
        T = (BiTNode *)malloc(sizeof(BiTNode));
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
void Rview(BiTree T)
{/**< 右视图算法,用队列作为辅助存储结构 */
   _______________________
}
int main()
{
    BiTree T;
    CreateBiTree(T);
    Rview(T);
    return 0;
}
 

输入格式

输入二叉树的先序序列(只包含大写字母和#,大写字母代表树节点)。
 

输出格式

输出右视图的结果序列。
 

输入样例

AB##C##
 

输出样例

AC
 

提示

层次遍历使用队列作为辅助结构,处理每一层的时队列的队尾元素就是每一层的最后一个节点。

树上摘樱桃

Description

网易2021校招笔试-算法工程师(正式第一批)

有一棵二叉树,树上的叶子节点定义为“樱桃”。现在需要找出树上有多少个满足如下子结构的“樱桃”串,即一串上刚好有两颗“樱桃”。
简单说,就是某个节点的左右孩子都是叶子节点,即为一个串。
比如如下的一棵树,红框标示的有两个符合要求的结构,答案就是2

正在上传…重新上传取消



 

输入格式

第一行两个正整数m, n,空格分开,分别代表总共有树上有多少个节点,和树上有多少条边,2<=m<=100,  1<=n<=100
下面有n行,每行为3个部分,用空格分割,第一个数字为某非叶子节点的id,
 第二个为该边为left还是right,第三个为子节点的id
注意:节点id彼此不会重复,id 1为根节点 
 

输出格式

一个整数,标示符合要求的结构的数量。
 

输入样例

10 9
1 left 2
1 right 3
2 left 4
2 right 5
3 right 6
6 left 7
6 right 8
8 left 9
8 right 10
 

输出样例

2
 

提示

如题目说明的第一个样例图,可以看到,2-4-5子串,8-9-10子串,两个子串符合条件,所以答案为2

二叉树的最长路径

Description

二叉树中,任意两个节点间都存在一条唯一的路径,请求出所有路径中最长的路径长度。


 

输入格式

第一行为一个整数n,表示结点个数,结点以数字编号,根节点为1。n<10
第二行为一个数字和#号组成的字符串,采用完全二叉树的存储形式,#表示空树。
 

输出格式

输出所有路径中最长的路径长度
 

输入样例

5
1234##5
 

输出样例

4
 

提示

样例最长路径为(4,5),路径长度为4

测验习题

不同的字符

描述

不同的字符
统计一个全部由小写字母组成的字符串中有多少种字符。
例如baddff有4种字符,分别是a,b,c,d
 

输入格式

仅一行,一个长度小于10000的字符串

输出格式

输出不同字符的个数。

输入样例

fabbddd

输出样例

4

组队

描述

组队

老师把学生们分为A和B两个小组,人数分别是n和m,每个成员都有一个具体的能力值。
现在打算派出一些队伍参加比赛,每个队伍必须由一名A组成员和一名B组成员组成,
且两个成员的能力值之和必须恰好为d。
请你计算下,最多可以派出多少支参赛队伍。
 

输入格式

第一行是三个整数n(1<=n<=1000)、m(1<=m<=1000)和d(1<=d<=100000000),分别表示A组人数,B组人数和要求的d。
第二行是n个整数ai(1<=ai<=100000000),表示A组成员的能力值。
第三行是m个整数bi(1<=bi<=100000000),表示B组成员的能力值。


输出格式

输出一个整数,表示最多可以派出多少支参赛队伍,答案可能为0。

输入样例

5  4  10
1  2  3  4  5
6  6  5  8

输出样例

3

小球(树结构)

描述

一颗满二叉树的每一个结点都有一个整数权值,现在一个小球从树根上下落,
下落过程中它可以选择左右两个分支的任意一个,并获取结点的权值。
请问当小球掉落到最后一层时,它能获取的最大值。如下图,二叉树序列11 4 2 5 1 9 3
的最大值为22,小球依次获取11,2,9。

正在上传…重新上传取消

 

输入格式

第一行一个整数n,代表满二叉树结点数量。n<=100
第二行n个整数,代表二叉树各结点权值。

输出格式

小球掉落到最后一层时,它能获取的最大值。

输入样例

7
11 4 2 5 1 9 3

输出样例

22

最小的特殊数字

描述

用全部N(N<=10)个0-9的数字组成一个“有效”整数(即没有前置0的整数),
求这些组成的数中能被K(0<K<10^10)整除的最小数字。
 

输入格式

输入分两行,第一行输入N, K,第二行输入N个数字。

输出格式

输出满足条件的最小的数(不含前置0),如果没有满足条件的数输出 -1。

输入样例

4 7
4 0 1 3

输出样例

1043

提示

413 % 7 = 0, 但是有前置0,所以满足条件的最小数是 1043 % 7 = 0。
此类题目需注意特殊情况,比如n=1时,如只输入一个0,答案只能是0。
注意long long

;