洛谷P1036 选数(递归)

题目描述

已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:

3+7+12=22

3+7+19=29

7+12+19=38

3+12+19=34。

现在,要求你计算出和为素数共有多少种。

例如上例,只有一种的和为素数:3+7+19=29)。

输入输出格式

输入格式:

键盘输入,格式为:

n , k (1<=n<=20,k<n)

x1,x2,…,xn (1<=xi<=5000000)

输出格式:

屏幕输出,格式为:

一个整数(满足条件的种数)。

输入输出样例

输入样例#1:  复制
4 3
3 7 12 19
输出样例#1:  复制
1



本人理解:这题需要从n个数选出k个数,即数学中的选数问题,可借助用递归实现全排列的思想来做这个题;

 以下是代码:

#include
using namespace std;
int s[200005],num[200005],w[200005],win[200005],lose[200005];//num【】编号
bool cmp(int x,int y)//对s[]进行排序,但实际不改变s[],仅对其对应的编号改变,并能实现但是s【x】==a【y】编号小的在前                                       面。

{
    return  s[x]==s[y]?xs[y];
}
void msort()//归并排序
{
    int i=1,j=1;
    num[0]=0;//存贮已处理好的人数,实现num【】的变化
    while(i<=win[0]&&j<=lose[0])//归并开始
    {
        if(cmp(win[i],lose[j]))//判断win【i】和lose【i】的大小,谁大谁存储到num【】中,并实现s【i】==s【j】编号小的在前面。
        {
            num[0]++;
            num[num[0]]=win[i];
            i++;
        }
        else
        {
            num[0]++;
            num[num[0]]=lose[j];
            j++;
        }
    }
        while(i<=win[0])//其中一个数组存储完了,同时另一个数组剩下的人分数全部小于num中的分数,并且剩下的数是有序的,只需接到num后面即可

        {
           num[0]++;
            num[num[0]]=win[i];
            i++;
        }
        while(j<=lose[0])
        {
            num[0]++;
            num[num[0]]=lose[j];
            j++;
        }


}
int main()
{
   int n,q,r,i,j;
   cin>>n>>r>>q;
   for(i=1;i<=2*n;i++)
    {
     num[i]=i;
     cin>>s[i];
    }
   for(i=1;i<=2*n;i++)
       cin>>w[i];
     sort(num+1,num+2*n+1,cmp);//快排一遍
     for(i=1;i<=r;i++)
     {
        win[0]=0;//【0】记录人数,充当数组下标
        lose[0]=0;
         for(j=1;j<=2*n;j+=2)
         {
             win[0]++;//每局比赛都有输赢
             lose[0]++;
             if(w[num[j]]>w[num[j+1]])//输赢的人分别放入各自数组,并s实现加分
             {
                 s[num[j]]++;
                 win[win[0]]=num[j];
                 lose[lose[0]]=num[j+1];
             }
             else
             {
                 s[num[j+1]]++;
                  win[win[0]]=num[j+1];
                 lose[lose[0]]=num[j];
             }
         }
         msort();
     }
    cout<

你可能感兴趣的:(洛谷P1036 选数(递归))