题解
- 首先,对于这题,我们可以发现,如果x[i]与y[i]差的和<10000000,可以直接枚举合法的数
- 将它们每一位数都截出来,将每一位上出现过什么都+1
- 最后枚举i,j,如果判断是否是等类的呢?
- 枚举每一位上,如果全部位上出现的次数都相等的话
- 两个数字就是等类的
- 然后再来考虑一下a[i]与b[i]的差>10000000
- 我们可以从一个为被访问过的数,往后拓展,再判断两者是否合法
- 那如果判断是否合法呢?
- ①对于y[i]-x[i]<100000
- 暴力枚举一个j(0<=j<=y[i]-x[i])
- 设t=x[i]+j
- 如果现在是判断a,b是否等类
- 从后往前将t每一位截出来
- 如果t==a,那么使p=w-a*i+b*i(i就是当前从后往前截到哪一位)
- 然后再所有x[i],y[i]的区间里跑,如果w在一个区间内,就是等类的
- 设t=y[i]-j
- 类似于上面的判断
- ②对于y[i]-x[i]>100000
- 枚举一个j(0<=j<=10000)
- 向上面一样判断一下
代码
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<cctype>
7 using namespace std;
8 long long n,k,visit[10],x[10010],y[10010],sum,f[100][13],a[10][20];
9 long long read()
10 {
11 long long X=0,w=0;
12 char ch=0;
13 while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
14 while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
15 return w?-X:X;
16 }
17 void doit(long long x)
18 {
19 long long t=x,len=1;
20 while (t)
21 {
22 if (len>k) break;
23 f[len][t%10]++; t=t/10; len++;
24 }
25 }
26 bool pd(long long a,long long b)
27 {
28 for (long long i=1;i<=k;i++)
29 if (f[i][a]!=f[i][b])
30 return 0;
31 return 1;
32 }
33 void work()
34 {
35 for (long long i=1;i<=n;i++)
36 for (long long j=x[i];j<=y[i];j++)
37 doit(j);
38 for (long long i=1;i<=9;i++)
39 if (!visit[i])
40 {
41 printf("%d",i);
42 for (long long j=i+1;j<=9;j++)
43 if (pd(i,j))
44 {
45 visit[j]=1;
46 printf("%d",j);
47 }
48 printf("\n");
49 }
50 }
51 bool find(long long a)
52 {
53 for (long long i=1;i<=n;i++)
54 if (a>=x[i]&&a<=y[i]) return 1;
55 return 0;
56 }
57 bool check(long long x,long long a,long long b)
58 {
59 long long w=x,p=1;
60 long long len=1;
61 while (w)
62 {
63 if (len>k) break;
64 if (w%10==a) if (!find(x-a*p+b*p)) return 0;
65 w=w/10; p=p*10; len++;
66 }
67 return 1;
68 }
69 bool pd1(long long a,long long b)
70 {
71 for (long long i=1;i<=n;i++)
72 {
73 if (y[i]-x[i]>100000)
74 {
75 for (long long j=0;j<10000;j++)
76 if ((check(x[i]+j,a,b)&&check(x[i]+j,b,a)&&check(y[i]-j,a,b)&&check(y[i]-j,b,a))==0) return 0;
77 }
78 else
79 {
80 for (long long j=0;j<=y[i]-x[i];j++)
81 {
82 if (j<=10||(x[i]+j)%10==0)
83 {
84 if ((check(x[i]+j,a,b)&&check(x[i]+j,b,a)&&check(y[i]-j,a,b)&&check(y[i]-j,b,a))==0) return 0;
85 }
86 else
87 {
88 long long w=x[i]+j;
89 if (w%10==a)
90 {
91 if (find(w-a+b)==0) return 0;
92 }
93 else
94 if (w%10==b)
95 {
96 if (find(w+a-b)==0) return 0;
97 }
98 }
99 }
100 }
101 }
102 return 1;
103 }
104 void dfs(long long x,long long y)
105 {
106 if (y>9) return;
107 if (pd1(x,y)) a[x][++a[x][0]]=y,visit[y]=1;
108 dfs(x,y+1);
109 }
110 void work1()
111 {
112 for (long long i=1;i<=9;i++)
113 if (!visit[i])
114 {
115 a[i][++a[i][0]]=i;
116 visit[i]=1;
117 dfs(i,i+1);
118 }
119 for (long long i=1;i<=9;i++)
120 if (a[i][0])
121 {
122 for (long long j=1;j<=a[i][0];j++) printf("%d",a[i][j]);
123 printf("\n");
124 }
125 }
126 int main()
127 {
128 n=read();k=read();
129 for (long long i=1;i<=n;i++) x[i]=read(),y[i]=read(),sum+=y[i]-x[i];
130 if (sum<10000000)
131 {
132 work();
133 return 0;
134 }
135 else
136 {
137 work1();
138 return 0;
139 }
140 }