鱼C论坛

 找回密码
 立即注册
查看: 3288|回复: 32

一道竞赛题,想了两天无果,虽然考试结束,我还是希望得到指点

[复制链接]
发表于 2016-12-16 08:47:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
/*本来想悬赏的,因为一道题的解惑比我的鱼币重要多了,但是提示我是新鱼友不让我发,厚脸皮希望各位帮帮我,
讲讲思路也好,不必写出代码*/
素数划分
Time Limit:1000MS  Memory Limit:65535K
题型: 编程题   语言: 无限制
描述
给定一个最多不超过30个字符的数字字符串(只由0到9,十个数字构成),如果将该字符串切割成
多段(每一段数字不超过6个字符),如果能找到一种划分使每一段构成的数字都是质数,则输出“YES”
,怎么也找不到,输出“NO”。
例如
1447160917891993
可以划分为
1447 1609 17 89 199 3
均为质数,输出YES

再例如
999444
输出NO

输入格式
不超过30个字符的数字串
输出格式
YES或NO
输入样例
1447160917891993
输出样例
YES
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-12-16 11:53:10 | 显示全部楼层
还没看懂,晚上看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-16 12:20:59 | 显示全部楼层
conn 发表于 2016-12-16 11:53
还没看懂,晚上看看

嗯嗯,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 16:47:09 | 显示全部楼层
回溯,从第一个字符开始找一个一个往后挪,如果构成了质数就接着往下一个子串找质数,同样的知道找到最后,如果找完了纯在就输出YES,否则就回溯到上一层再往下找,这整个过程可以用递归来完成的。。

我看看明天把代码贴上来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 16:49:05 | 显示全部楼层
其实相当于构造一颗搜索树
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-16 20:16:35 | 显示全部楼层
小山童鞋 发表于 2016-12-16 16:47
回溯,从第一个字符开始找一个一个往后挪,如果构成了质数就接着往下一个子串找质数,同样的知道找到最后, ...

今天下午想了一个下午才想到用递归,不过老是失败,没学过数据结构大神好厉害,几下就看出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-16 20:42:28 | 显示全部楼层
小山童鞋 发表于 2016-12-16 16:47
回溯,从第一个字符开始找一个一个往后挪,如果构成了质数就接着往下一个子串找质数,同样的知道找到最后, ...

查了一下递归,回溯,枚举感觉自己离我们系那些大神还差得好远
现在我有几个问题:1.回溯的话每次的情况需要控制不同,怎么控制,用if吗?只是我试了几次都失败实在没有          头绪 2.无限递归的话除非输出YES,否则只能等到满足超出6位数的条件来输出NO吗? 烦扰了,确实需要大神的代码参考,不过我保证要自己写出来,不是复制粘贴
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 21:35:21 | 显示全部楼层
honhon 发表于 2016-12-16 20:42
查了一下递归,回溯,枚举感觉自己离我们系那些大神还差得好远
现在我有几个问题:1.回溯的话 ...

我现在在刷其他题,最迟明天给你发代码,或者你可以加我QQ870817784.
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 21:42:16 | 显示全部楼层
直接贴代码行不行?
不知道还有没有潜在的bug
无标题.png
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. int is_prime_number_long_long(long long n)
  5. {
  6.         int i = 2;
  7.         while(i<n)
  8.         {
  9.                 if(n%i == 0)
  10.                 {
  11.                         break;
  12.                 }
  13.                 i++;
  14.         }

  15.         if(i == n)
  16.         {
  17.                 return 1;
  18.         }
  19.         else
  20.         {
  21.                 return 0;
  22.         }
  23. }

  24. int is_prime_number_str(char *begin, char *end)
  25. {
  26.         char buf[100];

  27.         if(end - begin > 6) return 0;

  28.         memcpy(buf, begin, end - begin + 1);
  29.         buf[end - begin + 1] = '\0';

  30.         long long number = atoll(buf);

  31.         return is_prime_number_long_long(number);
  32. }

  33. int str_prime_number(char str[], int str_len)
  34. {
  35.         for(int i = 0; i < str_len; i++)
  36.         {
  37.                 for(int j = i; j < str_len; j++)
  38.                 {
  39.                         if(is_prime_number_str(&str[i], &str[j]) == 1) return 1;
  40.                 }
  41.         }

  42.         return 0;
  43. }

  44. int main(void)
  45. {
  46.         char test_str[] = "1447160917891993";
  47.         char test_str2[] = "999444";

  48.         if(str_prime_number(test_str, strlen(test_str)) == 0)
  49.         {
  50.                 printf("NO\n");
  51.         }
  52.         else
  53.         {
  54.                 printf("YES\n");
  55.         }

  56.         if(str_prime_number(test_str2, strlen(test_str2)) == 0)
  57.         {
  58.                 printf("NO\n");
  59.         }
  60.         else
  61.         {
  62.                 printf("YES\n");
  63.         }

  64.         return 0;
  65. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 22:38:04 | 显示全部楼层
膜拜楼上
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 23:51:07 | 显示全部楼层
本帖最后由 小山童鞋 于 2016-12-17 00:10 编辑

给你参考下,搜索的写法。
我稍作修改了下,改成字符最多只能三位。原理是一样的。
  1. #include<cstdio>
  2. #include<string.h>
  3. //数组a用来保存解,ai为数组a的下标
  4. int a[1001] = {0};int ai=0;
  5. //素数访问表,通过isprim数组查询是否为素数
  6. int isnprim[1001]={0};
  7. //处理isnprim数组
  8. void deal()
  9. {
  10.     int i,j;isnprim[0]=1,isnprim[1]=1;
  11.     for(i=2;i<1001;i++)
  12.         for(j=i;j*i<1001;j++)
  13.         isnprim[j*i]=1;
  14. }
  15. //把字符数组转换成十进制数并返回
  16. int STI(char *sbeg,char *send)
  17. {
  18.     int n=0;
  19.     while(sbeg<=send)
  20.         n=n*10+*(sbeg++)-'0';
  21.     return n;
  22. }
  23. //有解标志
  24. int flag;
  25. //寻找解的函数
  26. int f(char *s)
  27. {
  28.     int len = strlen(s);
  29.     int i;
  30.     //如果越界就代表有解就打印解
  31.     if(len<=0)
  32.     {
  33.         flag = 1;
  34.         for(i=0;i<ai;i++)printf("%d ",a[i]);
  35.         putchar('\n');
  36.     }
  37.     else
  38.     {
  39.         //搜索可行解
  40.         for(i=0;i<3&&i<len;i++)
  41.         {
  42.             if(flag)return 1;
  43.             a[ai] = STI(s,s+i);
  44.             if(!isnprim[a[ai]])
  45.             {
  46.                 ai++;
  47.                 f(s+i+1);
  48.                 //回溯
  49.                 ai--;
  50.             }

  51.         }
  52.     }
  53. }

  54. int main()
  55. {
  56.     //调试用的文件
  57.     //freopen("Input.txt","r",stdin);
  58.     //freopen("Output.txt","w",stdout);
  59.     deal();
  60.     //将flag置0并调用f函数查询
  61.     flag = 0;
  62.     f("1331891995713193");
  63.     if(flag)puts("YES");
  64.     else puts("NO");
  65.     return 0;
  66. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-17 07:55:59 | 显示全部楼层
小山童鞋 发表于 2016-12-16 23:51
给你参考下,搜索的写法。
我稍作修改了下,改成字符最多只能三位。原理是一样的。

谢谢,我会好好研究的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-17 07:57:27 | 显示全部楼层
人造人 发表于 2016-12-16 21:42
直接贴代码行不行?
不知道还有没有潜在的bug

谢谢,我会好好研究的O(∩_∩)O
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 09:04:02 From FishC Mobile | 显示全部楼层
本帖最后由 小山童鞋 于 2016-12-17 09:05 编辑

你可以先去试着写一下排列组合的生成练练手。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 09:35:09 | 显示全部楼层
人造人 发表于 2016-12-16 21:42
直接贴代码行不行?
不知道还有没有潜在的bug

你可以试试这个“14471609178919934”
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 10:01:08 | 显示全部楼层
honhon 发表于 2016-12-17 07:57
谢谢,我会好好研究的O(∩_∩)O

能不能发现这道题的链接,我去试试能不能A掉。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 12:47:14 | 显示全部楼层
小山童鞋 发表于 2016-12-17 09:35
你可以试试这个“14471609178919934”

你指的是?
无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 14:08:13 From FishC Mobile | 显示全部楼层
这个是没办法构成解的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-17 17:00:58 | 显示全部楼层
小山童鞋 发表于 2016-12-17 10:01
能不能发现这道题的链接,我去试试能不能A掉。

不知道是不是学校的原创,过阵子考试结束后再次开放,我可以帮你把码贴去试试(因为学校的Oj只允许学生提交题。。。。)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 18:39:34 | 显示全部楼层
我也是ACM的,大一的,创个帐号应该能提交的。。。。

下面的代码如果提交不能AC那我再改改。。


  1. #include<cstdio>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. //数组a用来保存解,ai为数组a的下标
  5. //int a[1001] = {0};int ai=0;
  6. //素数访问表,通过isprim数组查询是否为素数
  7. int isnprim[1000001]={0};
  8. //处理isnprim数组
  9. void deal()
  10. {
  11.     int i,j;isnprim[0]=1,isnprim[1]=1;
  12.     for(i=2;i<1000001;i++)
  13.         for(j=i;j*i<1000001;j++)
  14.         {
  15.             if(j*i<=0)
  16.                 break;
  17.             isnprim[j*i]=1;
  18.         }
  19. }
  20. //把字符数组转换成十进制数并返回
  21. int STI(char *sbeg,char *send)
  22. {
  23.     int n=0;
  24.     while(sbeg<=send)
  25.         n=n*10+*(sbeg++)-'0';
  26.     return n;
  27. }
  28. //有解标志
  29. int flag;
  30. //寻找解的函数
  31. int f(char *s)
  32. {
  33.     int len = strlen(s);
  34.     int i;
  35.     //如果越界就代表有解就打印解
  36.     if(len<=0)
  37.     {
  38.         flag = 1;
  39.         //for(i=0;i<ai;i++)printf("%d ",a[i]);
  40.         //putchar('\n');
  41.     }
  42.     else
  43.     {
  44.         //搜索可行解
  45.         for(i=0;i<6&&i<len;i++)
  46.         {
  47.             if(flag)return 1;
  48.             //a[ai] = STI(s,s+i);
  49.             if(!isnprim[STI(s,s+i)])
  50.             {
  51.                 //ai++;
  52.                 f(s+i+1);
  53.                 //回溯
  54.                 //ai--;
  55.             }
  56.         }
  57.     }
  58. }

  59. int main()
  60. {
  61.     //调试用的文件
  62.     //freopen("Input.txt","r",stdin);
  63.     //freopen("Output.txt","w",stdout);
  64.     char s[1024];
  65.     deal();
  66.     while(~scanf("%s",s))
  67.     {
  68.         getchar();
  69.         flag=0;
  70.         f(s);
  71.         if(flag)puts("YES");
  72.         else puts("NO");
  73.     }
  74.     //将flag置0并调用f函数查询
  75.     //flag = 0;
  76.     //f("1447160917891993");
  77.     //if(flag)puts("YES");
  78.     //else puts("NO");
  79.     return 0;
  80. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 14:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表