sgu 537 Divisibility
2013-11-29 12:01
162 查看
题意:
给你一个字符串,其中的每个字母都可以对应0-9之间的一个数字,且不同的字母不能对应同一个数字,然后就得到了一个数字,求所有这些可能得到的数字的共同约数,最多出现10个不同的字母,字符串长度最大是14。
思路:
一看题目首先就感觉是暴力,10!大概300+W的复杂度,暴力求出来每一个数然后求它们的gcd,由于10^14比较大,直接枚举因子要10^7,所以先分解质因数,然后再dfs求所有情况。结果果断TLE,这时注意到有100个case,100*300W肯定会TLE啊。赛后看了别人的做法,当存在10个不同的字母时,可以直接特判,这样复杂度就可以降到9!*100,就可以过了!
后来听杨神说,这种题直接随机就行了...然后就写了一发随机,哎,坑爹~
代码:
sgu 537
给你一个字符串,其中的每个字母都可以对应0-9之间的一个数字,且不同的字母不能对应同一个数字,然后就得到了一个数字,求所有这些可能得到的数字的共同约数,最多出现10个不同的字母,字符串长度最大是14。
思路:
一看题目首先就感觉是暴力,10!大概300+W的复杂度,暴力求出来每一个数然后求它们的gcd,由于10^14比较大,直接枚举因子要10^7,所以先分解质因数,然后再dfs求所有情况。结果果断TLE,这时注意到有100个case,100*300W肯定会TLE啊。赛后看了别人的做法,当存在10个不同的字母时,可以直接特判,这样复杂度就可以降到9!*100,就可以过了!
后来听杨神说,这种题直接随机就行了...然后就写了一发随机,哎,坑爹~
代码:
#include<cstdio> #include<ctime> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; #define maxH 100 char ch[20],tem[20]; int pos[20],va[20],num,ansnum; LL b[100],f[100],ans[100000]; LL ret; const int N=10000010; int pr ,p[N/10],lp; void gp(){ for(int i=2;i<N;i++){ if(!pr[i])p[lp++]=pr[i]=i; for(int j=0;j<lp && i*p[j]<N;j++){ pr[i*p[j]]=p[j]; if(i%p[j]==0)break; } } } void gn(LL n,int &l,LL b[],LL f[]){ int i=0,t; l=0; while(n>1){ if(n<N) t=pr ; else{ t=n; for(;i<lp && n/p[i]>=p[i];i++) if(n%p[i]==0){ t=p[i]; break; } } f[l]=0; while(n%t==0) n/=t,f[l]++; b[l++]=t; } } void dfs(int pos,LL now){ if(pos==num){ ans[ansnum++]=now; return; } LL tem=1; for(int i=0;i<=f[pos];i++){ dfs(pos+1,now*tem); tem *=b[pos]; } } void print(LL x){ gn(x,num,b,f); ansnum=0; dfs(0,1); sort(ans,ans+ansnum); for(int i=0;i<ansnum;i++){ printf(" %I64d",ans[i]); } printf("\n"); } void solve(){ ret = -1; int len=strlen(ch); strcpy(tem,ch); sort(tem,tem+len); int newlen = unique(tem,tem+len)-tem; for(int i=0;i<len;i++){ pos[i] = lower_bound(tem,tem+newlen,ch[i])-tem; } for(int i=0;i<10;i++){ va[i] = i; } for(int i=0;i<maxH;i++){ random_shuffle(va,va+10); while(va[pos[0]]==0){ random_shuffle(va,va+10); } LL now=0; for(int j=0;j<len;j++){ now = now*10 + va[pos[j]]; } if(ret==-1) ret=now; else ret = __gcd(ret,now); if(ret==1) break; } print(ret); } int main(){ int T; gp(); srand(time(NULL)); scanf("%d",&T); for(int i=1;i<=T;i++){ scanf("%s",ch); printf("Case %d:",i); solve(); } return 0; }
sgu 537
相关文章推荐
- SGU 537 Divisibility
- SGU 537 Divisibility
- SGU 537 Divisibility 枚举
- SGU 210 Beloved Sons (KM)
- SGU104 Little shop of flowers
- sgu148 B-station(Bomb)
- SGU 495 期望 简单推公式
- 537. Complex Number Multiplication
- SGU 194 Reactor Cooling 无源汇带上下界可行流
- poj 1745 Divisibility(01背包)
- 537_隐藏键盘
- SGU 194 Reactor Cooling (有容量和下界的可行流)
- SGU 125. Shtirlits(dfs)
- SGU 275 - To xor or not to xor 按位贪心 线性基
- To xor or not to xor SGU - 275 gauss
- SGU 417. Heavy Disc(水题)
- SGU 143.Long Live the Queen(女王万岁)
- leetcode记录(1)112、278、537、771
- SGU,人品测试器
- SGU 103 Traffic Lights