sgu 537 Divisibility

题意:

  给你一个字符串,其中的每个字母都可以对应0-9之间的一个数字,且不同的字母不能对应同一个数字,然后就得到了一个数字,求所有这些可能得到的数字的共同约数,最多出现10个不同的字母,字符串长度最大是14。

 

思路:

  一看题目首先就感觉是暴力,10!大概300+W的复杂度,暴力求出来每一个数然后求它们的gcd,由于10^14比较大,直接枚举因子要10^7,所以先分解质因数,然后再dfs求所有情况。结果果断TLE,这时注意到有100个case,100*300W肯定会TLE啊。赛后看了别人的做法,当存在10个不同的字母时,可以直接特判,这样复杂度就可以降到9!*100,就可以过了!

  后来听杨神说,这种题直接随机就行了...然后就写了一发随机,哎,坑爹~

 

代码:

  1 #include<cstdlib>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<cmath>
  5 #include<cstdio>
  6 #include<vector>
  7 #include<algorithm>
  8 using namespace std;
  9 typedef long long LL;
 10 const int N = 100+10;
 11 int n;
 12 char s[N];
 13 int vis[N];
 14 int mp[N];
 15 int TT[N];
 16 LL mark;
 17 const int maxnode = 10000000+10;
 18 int pr[maxnode],p[maxnode],lp;
 19 void gp(){
 20     lp = 0;
 21     memset(pr,0,sizeof(pr));
 22     for (int i = 2; i < maxnode; i++) {
 23         if (!pr[i]) p[lp++] = pr[i] = i;
 24         for (int j = 0; j < lp && i * p[j] < maxnode; j++) {
 25             pr[i * p[j]] = p[j];
 26             if (i % p[j] == 0) break;
 27         }
 28     }
 29 }
 30 
 31 int flag;
 32 void dfs(int pos,LL tmp,int len) {
 33     if (flag == 1) return;
 34     if (pos == len) {
 35 
 36         if (mark == -1) mark = tmp;
 37         else mark = __gcd(mark,tmp);
 38         if (mark == 1) {
 39             flag = 1;
 40         }
 41         return;
 42     }
 43     LL p;
 44     int c = s[pos] - 'a';
 45     int mk = -1;
 46     if (mp[c] == -1){
 47         for (int i = 0; i < 10; i++) {
 48 
 49             if (vis[i] == 0) {
 50                 if (pos == 0 && i == 0) continue;
 51                 mk = i;
 52                 mp[c] = mk;
 53                 vis[mk] = 1;
 54                 dfs(pos+1,tmp * 10 + mk,len);
 55                 mp[c] = -1;
 56                 vis[mk] = 0;
 57             }
 58         }
 59     }
 60     else dfs(pos+1,tmp * 10 + mp[c],len);
 61 
 62 }
 63 int a[N],b[N];
 64 void gn(LL n,int &l,int b[],int f[]) {
 65     int i = 0, t;
 66     l = 0;
 67     while (n > 1) {
 68         if (n < maxnode) t = pr[n];
 69         else {
 70             t = n;
 71             for (; i < lp && n / p[i] >= p[i]; i++)
 72                 if (n % p[i] == 0) {
 73                     t = p[i];
 74                     break;
 75                 }
 76         }
 77         f[l] = 0;
 78         while (n % t == 0) {
 79             n /= t; f[l]++;
 80         }
 81         b[l++] = t;
 82     }
 83 
 84 }
 85 vector<LL> an;
 86 LL w[N][N];
 87 void dfs_pi(int pos,LL tmp,int n) {
 88     if (pos == n) {
 89         an.push_back(tmp);
 90         return;
 91     }
 92     for (int i = 0; i <= b[pos]; i++) {
 93         dfs_pi(pos+1,tmp * w[pos][i],n);
 94     }
 95 }
 96 void work(int n){
 97     an.clear();
 98     for (int i = 0; i < n; i++) {
 99         w[i][0] = 1;
100         for (int j = 1; j <= b[i]; j++) {
101             w[i][j] = w[i][j-1] * a[i];
102         }
103     }
104     dfs_pi(0,1,n);
105     sort(an.begin(),an.end());
106     int sz = an.size();
107     for (int i = 0; i < sz; i++) {
108         printf("%I64d%c",an[i], i == sz-1 ? '\n' : ' ');
109     }
110 }
111 void solve(){
112     memset(vis,0,sizeof(vis));
113     memset(mp,-1,sizeof(mp));
114     int len = strlen(s);
115     mark = -1;
116     flag = 0;
117     dfs(0,0,len);
118     int le = 0;
119     gn(mark,le,a,b);
120     work(le);
121 }
122 int main(){
123     gp();
124     int T,cas = 0; scanf("%d",&T);
125     while (T--) {
126         scanf("%s",s);
127         printf("Case %d: ",++cas);
128         memset(TT,0,sizeof(TT));
129         int cc=0;
130         int len = strlen(s);
131         int flag=0;
132         for(int i=0;i<len;i++){
133             if(!TT[s[i]-'a']) cc++;
134             TT[s[i]-'a']++;
135             if(TT[s[i]-'a']==4) flag=1;
136         }
137         if(cc==10){
138             if(len==10)
139                 cout<<"1 3 9"<<endl;
140             else if(len==13&&flag==1){
141                 cout<<"1 3"<<endl;
142             }
143             else{
144                 cout<<"1"<<endl;
145             }
146             continue;
147         }
148         if(cc==len){
149             cout<<1<<endl;
150             continue;
151         }
152         solve();
153     }
154     return 0;
155 }
sgu 537

 

随机代码:

  1 #include<cstdio>
  2 #include<ctime>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 typedef long long LL;
  8 #define maxH 100
  9 char ch[20],tem[20];
 10 int pos[20],va[20],num,ansnum;
 11 LL b[100],f[100],ans[100000];
 12 LL ret;
 13 
 14 const int N=10000010;
 15 int pr[N],p[N/10],lp;
 16 void gp(){
 17     for(int i=2;i<N;i++){
 18         if(!pr[i])p[lp++]=pr[i]=i;
 19         for(int j=0;j<lp && i*p[j]<N;j++){
 20             pr[i*p[j]]=p[j];
 21             if(i%p[j]==0)break;
 22         }
 23     }
 24 }
 25 
 26 void gn(LL n,int &l,LL b[],LL f[]){
 27     int i=0,t;
 28     l=0;
 29     while(n>1){
 30         if(n<N) t=pr[n];
 31         else{
 32             t=n;
 33             for(;i<lp && n/p[i]>=p[i];i++)
 34                 if(n%p[i]==0){
 35                     t=p[i];
 36                     break;
 37                 }
 38         }
 39         f[l]=0;
 40         while(n%t==0)
 41             n/=t,f[l]++;
 42         b[l++]=t;
 43     }
 44 }
 45 
 46 void dfs(int pos,LL now){
 47     if(pos==num){
 48         ans[ansnum++]=now;
 49         return;
 50     }
 51     LL tem=1;
 52     for(int i=0;i<=f[pos];i++){
 53         dfs(pos+1,now*tem);
 54         tem *=b[pos];
 55     }
 56 }
 57 void print(LL x){
 58     gn(x,num,b,f);
 59     ansnum=0;
 60     dfs(0,1);
 61     sort(ans,ans+ansnum);
 62     for(int i=0;i<ansnum;i++){
 63         printf(" %I64d",ans[i]);
 64     }
 65     printf("\n");
 66 }
 67 void solve(){
 68     ret = -1;
 69     int len=strlen(ch);
 70     strcpy(tem,ch);
 71     sort(tem,tem+len);
 72     int newlen = unique(tem,tem+len)-tem;
 73     for(int i=0;i<len;i++){
 74         pos[i] = lower_bound(tem,tem+newlen,ch[i])-tem;
 75     }
 76     for(int i=0;i<10;i++){
 77         va[i] = i;
 78     }
 79     for(int i=0;i<maxH;i++){
 80         random_shuffle(va,va+10);
 81         while(va[pos[0]]==0){
 82             random_shuffle(va,va+10);
 83         }
 84         LL now=0;
 85         for(int j=0;j<len;j++){
 86             now = now*10 + va[pos[j]];
 87         }
 88         if(ret==-1) ret=now;
 89         else ret = __gcd(ret,now);
 90         if(ret==1) break;
 91     }
 92     print(ret);
 93 }
 94 int main(){
 95     int T;
 96     gp();
 97     srand(time(NULL));
 98     scanf("%d",&T);
 99     for(int i=1;i<=T;i++){
100         scanf("%s",ch);
101         printf("Case %d:",i);
102         solve();
103     }
104     return 0;
105 }
sgu 537

 

 

posted @ 2013-11-29 12:01  破晓べ  阅读(286)  评论(0编辑  收藏  举报