[枚舉] Jzoj P3387 終極武器

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個數字分紅了哪些等價類,而且每行輸出一個等價類。
  本題描述比較抽象,請參考樣例解釋。
 

Input

第一行兩個整數N,k。

接下來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% 的隨機數據。

 

 

題解

  • 首先,對於這題,咱們能夠發現,若是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 }
相關文章
相關標籤/搜索