鱼C论坛

 找回密码
 立即注册
查看: 1621|回复: 5

[已解决]洛谷p1036 选数

[复制链接]
发表于 2022-7-9 16:17:46 | 显示全部楼层 |阅读模式

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

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

x
只a了一个点,找了好久,结果改了之后总是全错。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int k,n,ans;
  4. int a[20],b[100];
  5. bool pr[312501];
  6. void pro(){
  7.     for(int i=2;i<177;i++){
  8.         if(i%2==1||i==2){
  9.             for(int j=i*i;j<=312500;j+=2){
  10.                 if((j%i==0||pr[j])){
  11.                     pr[j]=true;
  12.                 }
  13.             }
  14.         }
  15.         else{
  16.             for(int j=i*i+1;j<=312500;j+=2){
  17.                 if(j%i==0||pr[j]){
  18.                     pr[j]=true;
  19.                 }
  20.             }
  21.         }
  22.         
  23.     }
  24. }
  25. // int cc(int ns){
  26. //     for(int i=0;i<ans;i++){
  27. //         if(ns==b[i]){
  28. //             return 0;
  29. //         }
  30. //     }
  31. //     b[ans]=ns;
  32. //     return 1;
  33. // }
  34. void z(int i,int an,int step){
  35.     if(step==k){
  36.         //cout<<an+a[i]<<endl;
  37.         if(!pr[an+a[i]]){
  38.             //ans+=cc(an+a[i]);
  39.             cout<<an+a[i]<<endl;
  40.             ans++;
  41.         }
  42.     }
  43.     else{
  44.         for(int l=i;l<=n;l++){
  45.             z(l+1,an+a[i],step++);
  46.         }
  47.     }
  48. }
  49. int main(){
  50.     pro();
  51.     cin>>n>>k;
  52.     for(int i=0;i<n;i++){
  53.         cin>>a[i];
  54.     }
  55.     int o=0;
  56.     for(int i=0;i<n-k;i++){
  57.         z(i,0,1);
  58.     }
  59.     cout<<ans;

  60.     return 0;
  61. }
复制代码
最佳答案
2022-7-11 09:57:32
本帖最后由 jhq999 于 2022-7-12 11:46 编辑

应该先把奇偶分类
然后奇数选择奇数个,偶数=k-选择奇数的个数
然后再判断和是否为素数(判断时枚举的因子应该都是奇数)
  1. typedef struct GETSUSU
  2. {
  3.     int *num,*jisu,*ousu,*numk;
  4.     int ncount,jisucount,ousucount,k;

  5.     int jisuseek,oususeek,jisuselect,tongjicount;


  6. }GSS,*pGSS;
  7. int ousu(pGSS pgss,int n)
  8. {
  9.     if(0==n)
  10.     {
  11.         for(int i=0;i<pgss->k;i++)
  12.         {
  13.             printf("%4d",pgss->numk[i]);
  14.         }
  15.         printf("\n");
  16.         pgss->tongjicount+=1;
  17.         return 1;
  18.     }
  19.     for(int i=pgss->oususeek;i<=pgss->ousucount-n;i++)
  20.     {
  21.         pgss->numk[pgss->jisuselect+n-1]=pgss->ousu[i];
  22.         pgss->oususeek=i+1;
  23.         ousu(pgss,n-1);
  24.         pgss->oususeek=i;
  25.     }
  26.     return 0;
  27. }
  28. int jisu(pGSS pgss,int n)
  29. {
  30.     if(0==n)
  31.     {
  32.         pgss->oususeek=0;
  33.         ousu(pgss,pgss->k-pgss->jisuselect);
  34.         return 1;
  35.     }
  36.     for(int i=pgss->jisuseek;i<=pgss->jisucount-n;i++)
  37.     {
  38.         pgss->numk[n-1]=pgss->jisu[i];
  39.         pgss->jisuseek=i+1;
  40.         jisu(pgss,n-1);
  41.         pgss->jisuseek=i;
  42.     }
  43.     return 0;
  44. }
  45. int combination(int a,int b)
  46. {
  47.     int sum1=1,sum2=1;
  48.     for(int i=a;i>a-b;i--)sum1*=i;
  49.     for(int i=1;i<=b;i++)sum2*=i;
  50.     return sum1/sum2;

  51. }
  52. int main()
  53. {
  54.     GSS gss;
  55.     int n=0,k=0,i=0,j=0,t=0;
  56.     scanf("%d%d",&n,&k);
  57.     gss.k=k;
  58.     gss.ncount=n;
  59.     gss.num=(int*)calloc(n,sizeof(int));
  60.     gss.numk=(int*)calloc(k,sizeof(int));
  61.     gss.jisuseek=gss.oususeek=0;
  62.     for(i=0,j=n-1;i<j+1;)
  63.     {
  64.         scanf("%d",&t);
  65.         if(t%2)gss.num[i++]=t;
  66.         else
  67.             gss.num[j--]=t;
  68.     }
  69.     gss.jisucount=i,gss.ousucount=n-i;
  70.     gss.jisu=gss.num,gss.ousu=gss.num+i;
  71.     for(i=0;i<n;i++)printf("%4d",gss.num[i]);
  72.     printf("\n");
  73.     gss.tongjicount=0;
  74.     int sum=0;
  75.     for(i=1;i<=gss.jisucount;i+=2)
  76.     {
  77.         sum+=combination(gss.jisucount,i)*combination(gss.ousucount,k-i);
  78.         gss.jisuseek=gss.oususeek=0;
  79.         gss.jisuselect=i;
  80.         jisu(&gss,i);
  81.     }

  82.     printf("\n%d",gss.tongjicount);
  83.     printf("\n%d",sum);
  84.     free(gss.numk);
  85.     free(gss.num);

  86.     return 0;
  87. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-7-9 19:36:23 | 显示全部楼层
我不知道对不对,你可以试试这个方法:
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;

  4. bool isPrime(int num) {
  5.         if (num < 2)return false;
  6.         else if (num == 2)return true;
  7.         for (int n = 2; n < pow(num, .5) + .5; ++n) {
  8.                 if (not (num % n)) {
  9.                         return false;
  10.                 }
  11.         }
  12.         return true;
  13. }

  14. // Depth-first search 深度优先搜索
  15. // arr: 数组, k: 相加的整数个数, num: 已相加多少个数? i: 当前数组位置, sum: 相加结果, res: 为素数个数
  16. unsigned DFS(const vector<int>& arr, int k, int num = 0, int i = 1, int sum = 0, int res = 0) {
  17.     if (num == k){
  18.         if (isPrime(sum)) return 1;
  19.         return 0;
  20.     }
  21.     for (int j = i; j < arr.size(); ++j) {
  22.         res += DFS(arr, k, num + 1, j + 1, sum + arr[j]);
  23.     }
  24.     return res;
  25. }

  26. int main()
  27. {
  28.     int n, k;
  29.     vector<int> arr;
  30.     arr.push_back(0);
  31.     cin >> n >> k;
  32.     for (int i = 1, num; i <= n; i++) {
  33.         cin >> num;
  34.         arr.push_back(num);
  35.     }
  36.     cout << DFS(arr, k);
  37.     return 0;
  38. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 3 反对 0

使用道具 举报

发表于 2022-7-9 19:57:13 | 显示全部楼层
这题我也有点蒙 , 感觉我的代码是可以过的 , 为什么过不去
  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. int nums[21], n, k, ans = 0; // 存数字
  4. bool vis[21]; // 看是否用过

  5. bool check(int n){ // 看是否是素数
  6.     int l = sqrt((float)n);
  7.     for(int i = 2; i <= l; i++){
  8.         if(n % i == 0) return 0;
  9.     }
  10.     return 1;
  11. }

  12. void dfs(int dep/*看用了几个数*/, int sum/*加起来的数*/){
  13.     if(dep == k){ // 用了 k 个数之后
  14.         if(check(sum)) ans++; // 符合条件就加上一种可能
  15.         return;
  16.     }
  17.     else{
  18.         for(int i = 0; i < n; i++){ // 遍历整个数组
  19.             if(!vis[i]){
  20.                 vis[i] = 1; // vis[i] 代表是否用过 i , 这里如果没用过就用
  21.                 dfs(dep + 1, sum + nums[i]); // 取的数 +1 , 加起来的数 +nums[i]
  22.                 vis[i] = 0; // 回溯 , 等他回来就恢复现场让它继续选
  23.             }     
  24.         }
  25.     }
  26. }

  27. int main(){
  28.     ios::sync_with_stdio(0);

  29.     cin >> n >> k;
  30.     for(int i = 0; i < n; i++){
  31.         cin >> nums[i];
  32.     }

  33.     dfs(0, 0);

  34.     cout << ans << endl;

  35.     return 0;
  36. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-9 19:57:44 | 显示全部楼层
傻眼貓咪 发表于 2022-7-9 19:36
我不知道对不对,你可以试试这个方法:


vis 数组为啥不行
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2022-7-9 20:12:04 | 显示全部楼层

会不会是全局变量有影响?你的代码递归前后都改变 vis 值,可能在其中搜索树根改变了它的值,让答案越变越多。而我的代码完全没有用全局,因为虽然全局变量可行,但递归 + 全局的变数太多,我懒的想,所以不用。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-11 09:57:32 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jhq999 于 2022-7-12 11:46 编辑

应该先把奇偶分类
然后奇数选择奇数个,偶数=k-选择奇数的个数
然后再判断和是否为素数(判断时枚举的因子应该都是奇数)
  1. typedef struct GETSUSU
  2. {
  3.     int *num,*jisu,*ousu,*numk;
  4.     int ncount,jisucount,ousucount,k;

  5.     int jisuseek,oususeek,jisuselect,tongjicount;


  6. }GSS,*pGSS;
  7. int ousu(pGSS pgss,int n)
  8. {
  9.     if(0==n)
  10.     {
  11.         for(int i=0;i<pgss->k;i++)
  12.         {
  13.             printf("%4d",pgss->numk[i]);
  14.         }
  15.         printf("\n");
  16.         pgss->tongjicount+=1;
  17.         return 1;
  18.     }
  19.     for(int i=pgss->oususeek;i<=pgss->ousucount-n;i++)
  20.     {
  21.         pgss->numk[pgss->jisuselect+n-1]=pgss->ousu[i];
  22.         pgss->oususeek=i+1;
  23.         ousu(pgss,n-1);
  24.         pgss->oususeek=i;
  25.     }
  26.     return 0;
  27. }
  28. int jisu(pGSS pgss,int n)
  29. {
  30.     if(0==n)
  31.     {
  32.         pgss->oususeek=0;
  33.         ousu(pgss,pgss->k-pgss->jisuselect);
  34.         return 1;
  35.     }
  36.     for(int i=pgss->jisuseek;i<=pgss->jisucount-n;i++)
  37.     {
  38.         pgss->numk[n-1]=pgss->jisu[i];
  39.         pgss->jisuseek=i+1;
  40.         jisu(pgss,n-1);
  41.         pgss->jisuseek=i;
  42.     }
  43.     return 0;
  44. }
  45. int combination(int a,int b)
  46. {
  47.     int sum1=1,sum2=1;
  48.     for(int i=a;i>a-b;i--)sum1*=i;
  49.     for(int i=1;i<=b;i++)sum2*=i;
  50.     return sum1/sum2;

  51. }
  52. int main()
  53. {
  54.     GSS gss;
  55.     int n=0,k=0,i=0,j=0,t=0;
  56.     scanf("%d%d",&n,&k);
  57.     gss.k=k;
  58.     gss.ncount=n;
  59.     gss.num=(int*)calloc(n,sizeof(int));
  60.     gss.numk=(int*)calloc(k,sizeof(int));
  61.     gss.jisuseek=gss.oususeek=0;
  62.     for(i=0,j=n-1;i<j+1;)
  63.     {
  64.         scanf("%d",&t);
  65.         if(t%2)gss.num[i++]=t;
  66.         else
  67.             gss.num[j--]=t;
  68.     }
  69.     gss.jisucount=i,gss.ousucount=n-i;
  70.     gss.jisu=gss.num,gss.ousu=gss.num+i;
  71.     for(i=0;i<n;i++)printf("%4d",gss.num[i]);
  72.     printf("\n");
  73.     gss.tongjicount=0;
  74.     int sum=0;
  75.     for(i=1;i<=gss.jisucount;i+=2)
  76.     {
  77.         sum+=combination(gss.jisucount,i)*combination(gss.ousucount,k-i);
  78.         gss.jisuseek=gss.oususeek=0;
  79.         gss.jisuselect=i;
  80.         jisu(&gss,i);
  81.     }

  82.     printf("\n%d",gss.tongjicount);
  83.     printf("\n%d",sum);
  84.     free(gss.numk);
  85.     free(gss.num);

  86.     return 0;
  87. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-17 00:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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