SGU 537 Divisibility

537. Divisibility


Time limit per test: 3 second(s)
Memory limit: 262144 kilobytes
input: standard
output: standard


Inspired by Stephen Graham, the King of Berland started to study algorithms on strings. He was working days and nights, having a feeling that the full potential in this area is still to be unlocked. And he was right!


One day, all the sudden, he made a huge breakthrough by discovering the fact that strings can be magically transformed into integer numbers. It was so simple! You just have to map different letters to different digits and be careful enough not to introduce any leading zeroes.


Here is what he wrote in his textbook about the string 'lalala':
it can be transformed to an 282828 by mapping 'l' to 2, and 'a' to 8
it can also be transformed to 909090 by mapping 'l' to 9, and 'a' to 0
a couple of examples of invalid transformations are 050505 (the resulting number has a leading zero), 333333 (different letters are mapped to the same digit), 123456 (no mapping to the original letters at all)




But then things started to become more interesting. Obviously, it was known from very beginning that a single string can potentially be mapped to a variety of different integer numbers. But the King couldn't even imagine that all numbers produced by the same string pattern might have common properties!


For example, every single number that can be produced from string 'lalala' is always divisible by 259, irrespective of the letter-to-digit mapping you choose. Fascinating!


So the King ended up with the following problem. For any given string, he wanted to come up with an algorithm to calculate the set of its divisors. A number is called a divisor of the given string if all positive integers, that could possibly be produced from the given string, are divisible by it.


As usual, the King desperately wants you to help him, so stop thinking and start acting!


Input
Input consists of multiple test cases. The first line of input contains an integer number n (1 ≤ n ≤ 100) — the number of test cases.


Each of the next n lines contains a string pattern to be processed. Each pattern consists of lowercase Latin letters. Its length will always be between 1 and 14 characters, and the number of different characters in the pattern will never exceed 10 to ensure correct mapping to digits 0-9.


Output
For every test case print a line with the corresponding test case number and the calculated list of divisors. Output positive divisors in an increasing order, separating them with a single space. Format your output according to the example given in the sample test case.


Example(s)
sample input
sample output
5
cat
bbb
ololo
lala
icpcicpc
Case 1: 1
Case 2: 1 3 37 111
Case 3: 1
Case 4: 1 101

Case 5: 1 73 137 10001


SGU恶心的题目,传说中楼教主现场比赛的时候也被卡了好几次。终于在无数次猥琐+恶心的优化剪枝下AC了,顿时内牛满面。

大概题意:给你一个字符串,每个不同的字母分别映射一个对应(0~9)的数字,每个字母映射的数字不同,且最后得出的数不能有前导0,问哪些数无论怎样的映射关系都是它的约数。

基本思路:枚举各种可能的映射关系,对所有得出的数求一个gcd(), 然后最后的答案就是这个gcd()的所有约数。

鉴于这题题目太恶心了,各种YY和猥琐剪枝勉强水过,不知道正解怎样做。求各大神赐教正解...

代码极其猥琐恶心,看看就算了~

#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#define Maxn 10000010
#define Maxnum 10000010
#define lim 130706
using namespace std;

string s;
map<char, int> gid;
int p[20], ans, tot, cnt, np;
long long d[Maxn], num;
long long pa[800010], ti[800010], c[800010];
int nc;
bool vis[12], pri[Maxnum];

long long  gcd(long long a, long long b)
{
    if (a%b == 0) return b;
    else return gcd(b, a%b);
}
inline long long calc()
{
    long long ret = 0;
    for (int i=0; i<s.length(); i++)
        ret = ret*10 + p[gid[s[i]]-1];
    return ret;
}

void dfs(int dep)
{
    if (num == 1 || cnt > lim) return;
    if (dep >= tot)
    {
        cnt++;
        if (num == -1) num = calc();
        else num = gcd(num, calc());
        return;
    }
    else
    {
        if (dep&1)
        {
                for (int i=9; i>=0; i--)
        if (!vis[i])
        {
            if ((i == 0 && dep == 0) || (dep==tot-1 && i == 0)) continue;         
            vis[i] = true;
            p[dep] = i;
            dfs(dep+1);
           vis[i] = false;
        }          
        }
        else
        for (int i=0; i<=9; i++)
        if (!vis[i])
        {
            if ((i == 0 && dep == 0) || (dep==tot-1 && i == 0)) continue;          
            vis[i] = true;
            p[dep] = i;
            dfs(dep+1);         
            vis[i] = false;
        }
    }
}
void init()
{
     np = 0;
     memset(pri, true, sizeof(pri));
     for (long long i=2; i<=10000000; i++)
     if (pri[i])
     {
        pa[np++] = i;
        for (long long j=i*i; j<=10000000; j+=i) pri[j] = false;
     }  
     }
void work(long long m)
{
     nc = 0;
     int tmp = 0;
     for (int i=0; i<np; i++)
     {
         if (pa[i] > m) break;
         if (m % pa[i] == 0)
         {
               tmp = 0;
               while (m % pa[i] == 0)
               {
                  m/=pa[i];
                  tmp++;                     
               }
               ti[nc] = tmp;
               c[nc++] = pa[i];   
         }
     }
     if (m != 1) ti[nc] = 1, c[nc++] = m;
     return;
     }
void make(int idx, long long sum) 
{ 
     if (idx >= nc)
     {
         d[ans++] = sum;
         return;             
     }
     make(idx+1, sum); 
     long long st = 1;
     for (int i=1; i<=ti[idx]; i++) 
     {
         st *= c[idx];
         make(idx+1, sum * st);
     } 
     return;  
     }
int main()
{
    ios::sync_with_stdio(false);
    int T, ca=0;
    cin >>T;
    init();
    while (T--)
    {
        cin >>s;
        gid.clear();
        tot = cnt = 0;
        for (int i=0; i<s.length(); i++)
          if (gid.find(s[i]) == gid.end()) gid[s[i]] = ++tot;
        num = -1;
        memset(vis, false, sizeof(vis));
        dfs(0);
        cout <<"Case "<<++ca<<":";
        ans = 0;
        work(num);
        make(0, 1);
        sort(d, d+ans);
        for (int j=0; j<ans; j++) cout <<" "<<d[j];
        cout <<endl;
    }
  
    return 0;
}


你可能感兴趣的:(Algorithm,String,properties,Integer,output,stdstring)