思路:每个位置有0~9共10种可能,而总共有n位,则有10^^n种,再减去不该有的(满足保留号码开头的),而保留号码开头的,由于确定了x位,所以只有10^^(n-x)种,时间复杂度应该是O(n^^2);
个人处理时的难点:
1.采用long long int 记录可能种数,可能不够大,用的数组记录,这样就会涉及数组加减。
2.原本保留号码直接存在包含(不是一般的包含,只是首部开始包含)关系,会导致重复(短的在这里种数是包含了长的那部分),所以先将数据按升序排列,然后从较短数列开始遍历,如果后面有包含这个数列的长数列,则长数列化为‘a’,去重。
#include<bits/stdc++.h>
using namespace std;

int find(char s1[],char s2[])
{
    int flag=1;
    for(int j=0;j<strlen(s1)&&flag;j++)
    if(s2[j]!=s1[j])
    {
         flag=0;         
    }
    return flag;
}//判断是否包含字串;

int len(int a[],int num)
{
    int n=0;
    for(int i=num-1;i>=0;i--)
    {
        if(a[i]>0)
        {
            n=i;
            break;
        }
    }
    return n+1;
}//确定int数组的最高位数——————数组表示数需要;

int mycmp(int s1[],int s2[],int num)
{
    int flag=0;
    for(int i=num-1;i>=0&&flag==0;i--)
    {
        if(s1[i]>s2[i])
        {
            flag=1;
        }
        else if(s1[i]<s2[i])
        {
            flag=-1;
        }
    }
    return flag;
}//比较int数组之间的大小————数组表示数需要;

int main(void)
{
    int n,m;
    cin>>n>>m;
    char limit_num[50][18];
    for(int i=0;i<m;i++)
    {
      cin>>limit_num[i];
    }

    /*对保留号码数组进行排序*/
    for(int i=0;i<m-1;i++)
        for(int k=m-1;k>i;k--)
        {
            if(strcmp(limit_num[k],limit_num[k-1])<0)
            {
                char x[18];
                strcpy(x,limit_num[k]);
                strcpy(limit_num[k],limit_num[k-1]);
                strcpy(limit_num[k-1],x);
            }
        }
        /*去除包含的重复保留号码数组*/
    for(int i=0;i<m-1;i++)
    {
        if(strcmp(limit_num[i],"a")!=0)
        for(int k=i+1;k<m;k++)
        {
            if(find(limit_num[i],limit_num[k]))
            strcpy(limit_num[k],"a");
        } 
    }
        /*计算保留号码的种数*/
    int minus[50]={0};
    for(int i=0;i<m;i++)
        if(strcmp(limit_num[i],"a")!=0)
        {
            minus[n-strlen(limit_num[i])]++;
            if(minus[n-strlen(limit_num[i])]>=10)
            {
                minus[n-strlen(limit_num[i])+1]++;
                minus[n-strlen(limit_num[i])]-=10;
            }
        }
        /*总数减去保留号码种数*/
    int result[50]={0};
    result[n]=1;
    if(mycmp(minus,result,50)>=0)
    {
        cout<<0;
    }
    else
    {
    for(int i=0;i<50;i++)
    {
        result[i]-=minus[i];
        if(result[i]<0)
        {
            result[i]+=10;
            result[i+1]--;
        }   
    }
    int flag=0;
    for(int i=n;i>=0;i--)
    {
      if(result[i]>0&&!flag)
      {
         flag=1;
         cout<<result[i];
      }
      else if(flag)
        cout<<result[i];
    }
        
    }
    return 0;
}