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 }
随机代码:
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 }