Description
经过一番周折,精英队伍的队员们终于来到了关押applepi的牢狱面前。心中神一般的领袖applepi就在眼前,队员们都不由自主地跪烂膝盖……不过令他们沮丧的是,牢狱的大锁没有钥匙孔,黑魔法师Vani根本就没有指望它再被打开。幸好队员们携带了新研制的终极武器——k型氙激光器(Xenon Laser - k,代号XLk),可以用来破拆这把锁。不过作为一道终极武器,它的启用规则异常严格。
Xenon Laser - k上共有N个波段能够发射激光,每个波段可以用一个闭区间[ai,bi]来表示,其中ai,bi为正整数,b[i-1]<ai≤bi。对于两个数字p和q,如果对于这N个波段内的任意一个整数num,把它在十进制表示下的后k位中某一位上的p换成q(或者q换成p),都满足得到的整数仍然在这N个波段内,那么称在该激光器中,数字p和q是k等价的。我们称两两之间k等价的数字组成一个k等价类。
激光器附带了9个发射匣,代表1~9这9个数字。只有把同一个等价类的数字对应的发射匣安置在一排上,Xenon Laser - k才能够启动。给定个波段,现在就请你求出1~9这9个数字分成了哪些等价类,并且每行输出一个等价类。
本题描述比较抽象,请参考样例解释。
Xenon Laser - k上共有N个波段能够发射激光,每个波段可以用一个闭区间[ai,bi]来表示,其中ai,bi为正整数,b[i-1]<ai≤bi。对于两个数字p和q,如果对于这N个波段内的任意一个整数num,把它在十进制表示下的后k位中某一位上的p换成q(或者q换成p),都满足得到的整数仍然在这N个波段内,那么称在该激光器中,数字p和q是k等价的。我们称两两之间k等价的数字组成一个k等价类。
激光器附带了9个发射匣,代表1~9这9个数字。只有把同一个等价类的数字对应的发射匣安置在一排上,Xenon Laser - k才能够启动。给定个波段,现在就请你求出1~9这9个数字分成了哪些等价类,并且每行输出一个等价类。
本题描述比较抽象,请参考样例解释。
Input
第一行两个整数N,k。
接下来N行每行两个整数ai,bi。ai,bi为正整数,满足b[i-1]<ai<=bi。
接下来N行每行两个整数ai,bi。ai,bi为正整数,满足b[i-1]<ai<=bi。
Output
每行一个等价类,各行之内都按照数字从小到大排序,数字中间没有空格,行与行之间按照等价类中最小的数字从小到大排序。具体格式参考样例。
Sample Input
样例输入1 1 1 1 566 样例输入2 1 2 30 75
Sample Output
样例输出1 123456 789 样例输出2 12 345 6 7 89 样例解释: 第一个样例中,只允许修改个位。对于1~559这些数,个位无论如何修改都在波段内。对于560~566这些数,个位修改为大于等于7的数字时(例如562的2修改为8),就不在波段内了。因此1~6和7~9属于不同的等价类。 第二个样例每一位上都可以修改。修改方法与上面一个样例类似。
Data Constraint
对于25% 的数据,1<=n<=50,1<=ai<=bi<=6000。
对于另25% 的数据,n=1。
对于另30% 的数据,k=1。
对于100% 的数据,1<=n<=10000,1<=k<=19,1<=ai<=bi<=10^18。
在所有的数据中,均匀分布着25% 的随机数据。
对于另25% 的数据,n=1。
对于另30% 的数据,k=1。
对于100% 的数据,1<=n<=10000,1<=k<=19,1<=ai<=bi<=10^18。
在所有的数据中,均匀分布着25% 的随机数据。
题解
- 首先,对于这题,我们可以发现,如果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 }