zoukankan      html  css  js  c++  java
  • 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 ? '
    ' : ' ');
    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("
    ");
     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
  • 相关阅读:
    RavenScheme简介
    我终于理解了LISP『代码即数据|数据即代码』的含义
    汉编随想(一)
    SICP的一些练习题
    linux下Script小计
    vscode小计
    软硬连接区别
    find过滤大小执行操作
    pyqt5和qt designer安装
    pyenv和virtualenv结合使用管理多python环境
  • 原文地址:https://www.cnblogs.com/SolarWings/p/3449304.html
Copyright © 2011-2022 走看看