• POJ -- 3842


    An Industrial Spy
     

    Description

    Industrial spying is very common for modern research labs. I am such an industrial spy - don't tell anybody! My recent job was to steal the latest inventions from a famous math research lab. It was hard to obtain some of their results but I got their waste out of a document shredder. 
    I have already reconstructed that their research topic is fast factorization. But the remaining paper snippets only have single digits on it and I cannot imagine what they are for. Could it be that those digits form prime numbers? Please help me to find out how many prime numbers can be formed using the given digits.

    Input

    The first line of the input holds the number of test cases c (1 <= c <= 200). Each test case consists of a single line. This line contains the digits (at least one, at most seven) that are on the paper snippets.

    Output

    For each test case, print one line containing the number of different primes that can be reconstructed by shuffling the digits. You may ignore digits while reconstructing the primes (e.g., if you get the digits 7 and 1, you can reconstruct three primes 7, 17, and 71). Reconstructed numbers that (regarded as strings) differ just by leading zeros, are considered identical (see the fourth case of the sample input).

    Sample Input

    4
    17
    1276543
    9999999
    011

    Sample Output3

    1336
    0
    2

    题意:给你一串数字,问你他们能组成多少个不同的素数。

    思路:枚举这些数字的组合的排列,打一张素数表直接判断。这题时间限制很紧啊(1000ms),在无限TLE之后,我把memset(vis,0,sizeof(vis))这句删除之后跑了844ms,险过,memset怎么会那么坑,不是说内部实现是调用批处理吗,为什么还那么慢???
    另外,打素数表的时候,注意姿势。。。,不然必然超时。
    Ps:按照刚进实验室时某大三学长教我的那个写法打素数表时超时,当时他还说两种方法都一样,现在才发现坑了我们。
    下面是三个版本的:

    1.dfs+二进制枚举优化 (844ms)
     1 #include<cstdio>
     2 #include<string>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define MAXN 10000000
     6 char isp[MAXN], visp[MAXN], vis[MAXN];
     7 int a[10], t[10], sum;
     8 void init(){
     9     memset(isp, 0, sizeof(isp));
    10     isp[0] = isp[1] = 1;
    11     for(int i = 2;i*i<MAXN;i ++)
    12         if(!isp[i])
    13             for(int j = i*i;j < MAXN;j += i)
    14                 isp[j] = 1;
    15     return;
    16 }
    17 int ToNum(int n){
    18     int sum = 0;
    19     for(int i = 0;i < n;i ++) sum = sum*10 + t[i];
    20     return sum;
    21 }
    22 void dfs(int n, int dep){
    23     if(dep == n){
    24         int tmp = ToNum(n);
    25         if(!isp[tmp] && !visp[tmp]){
    26             sum++;
    27             visp[tmp] = 1;
    28         }
    29         return;
    30     }
    31     for(int i = 0;i < n;i ++){
    32         if(!vis[i]){
    33             vis[i] = 1;
    34             t[dep] = a[i];
    35             dfs(n, dep+1);
    36             vis[i] = 0;
    37         }
    38     }
    39 }
    40 int main(){
    41     char str[10];
    42     int tt, n, b[10];
    43     init();
    44     scanf("%d", &tt);
    45     while(tt--){
    46         memset(str, 0, sizeof(str));
    47         scanf("%s", str);
    48         int len = strlen(str);
    49         for(int i = 0;i < len;i ++) b[i] = str[i]-'0';
    50         memset(visp, 0, sizeof(visp));
    51         int ans = 0;
    52         int UP = (1 << len);
    53         for(int i = 1;i < UP;i ++){
    54             int k = 0;
    55             for(int j = 0;j < len;j ++)
    56                 if(i & (1 << j)) a[k++] = b[j];
    57             sum = 0;
    58             //memset(vis,0,sizeof(vis); 这句加上就超时。。。
    59             dfs(k, 0);
    60             ans += sum;
    61         }
    62         printf("%d
    ", ans);
    63     }
    64     return 0;
    65 }
    
    

    2. 普通dfs不加优化(969ms。。。)

    
    
     1 #include<cstdio>
     2 #include<string>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define MAXN 10000000
     6 char isp[MAXN], visp[MAXN], vis[MAXN];
     7 int a[10], t[10], sum;
     8 void init(){
     9     memset(isp, 0, sizeof(isp));
    10     isp[0] = isp[1] = 1;
    11     for(int i = 2;i*i<MAXN;i ++)
    12         if(!isp[i])
    13             for(int j = i*i;j < MAXN;j += i)
    14                 isp[j] = 1;
    15     return;
    16 }
    17 int ToNum(int n){
    18     int sum = 0;
    19     for(int i = 0;i < n;i ++) sum = sum*10 + t[i];
    20     return sum;
    21 }
    22 void dfs(int n, int dep, int cnt){
    23     if(dep == cnt){
    24         int tmp = ToNum(cnt);
    25         if(!isp[tmp] && !visp[tmp]){
    26             sum++;
    27             visp[tmp] = 1;
    28         }
    29     }
    30     for(int i = 0;i < n;i ++){
    31         if(!vis[i]){
    32             vis[i] = 1;
    33             t[dep] = a[i];
    34             dfs(n, dep+1, cnt);
    35             vis[i] = 0;
    36         }
    37     }
    38 }
    39 int main(){
    40     char str[10];
    41     int tt, n;
    42     init();
    43     scanf("%d", &tt);
    44     while(tt--){
    45         memset(str, 0, sizeof(str));
    46         scanf("%s", str);
    47         int len = strlen(str);
    48         for(int i = 0;i < len;i ++) a[i] = str[i]-'0';
    49         memset(visp, 0, sizeof(visp));
    50         int ans = 0;
    51         for(int i = 1;i <= len;i ++){
    52             //memset(vis, 0, sizeof(vis)); 加上就超时。。。
    53             sum = 0;
    54             dfs(len, 0, i);
    55             ans += sum;
    56         }
    57         printf("%d
    ", ans);
    58     }
    59     return 0;
    60 }
    
    
    3.C++ STL库 next_permutation(a,a+k)函数 + 二进制优化(813ms),可以看出并不比dfs快多少,况且没有调用ToNum函数,减少了程序运行时跳转的时间
     1 #include<cstdio>
     2 #include<string>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define MAXN 10000000
     6 using namespace std;
     7 char isp[MAXN], visp[MAXN], vis[MAXN];
     8 int a[10], t[10], sum;
     9 void init(){
    10     memset(isp, 0, sizeof(isp));
    11     isp[0] = isp[1] = 1;
    12     for(int i = 2;i*i<MAXN;i ++)
    13         if(!isp[i])
    14             for(int j = i*i;j < MAXN;j += i)
    15                 isp[j] = 1;
    16     return;
    17 }
    18 int ToNum(int n){
    19     int sum = 0;
    20     for(int i = 0;i < n;i ++) sum = sum*10 + a[i];
    21     return sum;
    22 }
    23 void dfs(int n, int dep){
    24     if(dep == n){
    25         int tmp = ToNum(n);
    26         if(!isp[tmp] && !visp[tmp]){
    27             sum++;
    28             visp[tmp] = 1;
    29         }
    30         return;
    31     }
    32     for(int i = 0;i < n;i ++){
    33         if(!vis[i]){
    34             vis[i] = 1;
    35             t[dep] = a[i];
    36             dfs(n, dep+1);
    37             vis[i] = 0;
    38         }
    39     }
    40 }
    41 int main(){
    42     char str[10];
    43     int tt;
    44     init();
    45     scanf("%d", &tt);
    46     while(tt--){
    47         memset(str, 0, sizeof(str));
    48         scanf("%s", str);
    49         int len = strlen(str);
    50         sort(str, str+len);
    51         memset(visp, 0, sizeof(visp));
    52         int ans = 0, UP = (1 << len);
    53         for(int i = 1;i < UP;i ++){
    54             int k = 0;
    55             for(int j = 0;j < len;j ++)
    56                 if((i >> j) & 1) a[k++] = str[j]-'0';
    57             sum = 0;
    58             //memset(vis,0,sizeof(vis)) 加上同样超时。。。
    59             do{
    60                 int tmp = 0;
    61                 for(int i = 0;i < k;i ++) tmp = tmp*10+a[i];
    62                 if(!isp[tmp] && !visp[tmp]){
    63                     sum++;
    64                     visp[tmp] = 1;
    65                 }
    66             }while(next_permutation(a, a+k));
    67             ans += sum;
    68         }
    69         printf("%d
    ", ans);
    70     }
    71     return 0;
    72 }    
    
    
    
     
    
    
    


    
    
    
     
  • 相关阅读:
    JS数字指定长度不足前补零的实现
    IIS7设置将域名不带www跳转到带www上
    NET Core Mvc发布带视图文件的方法!
    NET Core 部署到 Windows服务
    Java配置----JDK开发环境搭建及环境变量配置
    Windows上MyEclipse2017 CI7 安装、破解以及配置
    C# 通过http post 请求上传图片和参数
    MongoDB中的数据导出为excel CSV 文件
    JS计算两个日期之间的天数,时间差计算
    IIS8.5 的环境下添加配置WCF服务!!!!!
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3689848.html
Copyright © 2020-2023  润新知