题目要求:给两个数k和s,在不大于s的数中找出k不想等的数,要求k个数的公约数大于1

题目分析:在不大于s的所有数中,公约数是 i (i>2)的个数为 s/i ,所以求出 i 为素数,c(s/i,k)的所有和 //(c(n,m)表示求组合数)

但是纯粹这样求出后中间就会有重复计算,例如,当k=2,s=12时,公约数为2的数有2,4,6,8,10,12;公约数为3的数有3,6,9,12

这样6和12就重复计算了,所以计算后应减去这部分重复的,利用容斥原理求解即可。

对于求解组合数,求出杨辉三角即可

View Code
#include<iostream>
#include<cstring>
using namespace std;

int p[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int c[30][30];

void Getc()    //求出组合数,即杨辉三角
{
    int i,j;
    memset(c,0,sizeof(c));
    for(i=0;i<26;i++)
    {
        for(j=0;j<=i;j++)
        {
            if(i==j||j==0)
                c[i][j]=1;
            else
                c[i][j]=c[i-1][j]+c[i-1][j-1];
        }        
    }
}

int main()
{
    int k,s,sum,i,t,num[50];
    Getc();
    while(cin>>k>>s)
    {
        memset(num,0,sizeof(num));
        for(t=0;s/p[t]>=k;t++)
        {
            num[t]=s/p[t];
        }
        for(i=0,sum=0;i<t;i++)
        {
            sum+=c[num[i]][k];    //求出所有的可能的和
        }
        sum-=c[s/6][k];        //减去重复部分,容斥原理
        sum-=c[s/10][k];
        sum-=c[s/14][k];
        sum-=c[s/15][k];
        sum-=c[s/21][k];
        sum-=c[s/22][k];
        if(sum>10000)
            sum=10000;
        cout<<sum<<endl;
    }
    return 0;
}

一些测试数据

View Code
 1 2 2 0
 2 2 3 0
 3 2 4 1
 4 2 5 1
 5 2 6 4
 6 2 7 4
 7 2 8 7
 8 2 9 9
 9 2 10 14
10 2 11 14
11 2 12 21
12 2 13 21
13 2 14 28
14 2 15 34
15 2 16 41
16 2 17 41
17 2 18 52
18 2 19 52
19 2 20 63
20 2 21 71
21 2 22 82
22 2 23 82
23 2 24 97
24 2 25 101
25 2 26 114
26 2 27 122
27 2 28 137
28 2 29 137
29 2 30 158
30 2 31 158
31 2 32 173
32 2 33 185
33 2 34 202
34 2 35 212
35 2 36 235
36 2 37 235
37 2 38 254
38 2 39 268
39 2 40 291
40 2 41 291
41 2 42 320
42 2 43 320
43 2 44 343
44 2 45 363
45 2 46 386
46 2 47 386
47 2 48 417
48 2 49 423
49 2 50 452
50 3 2 0
51 3 3 0
52 3 4 0
53 3 5 0
54 3 6 1
55 3 7 1
56 3 8 4
57 3 9 5
58 3 10 11
59 3 11 11
60 3 12 24
61 3 13 24
62 3 14 39
63 3 15 46
64 3 16 67
65 3 17 67
66 3 18 104
67 3 19 104
68 3 20 143
69 3 21 159
70 3 22 204
71 3 23 204
72 3 24 277
73 3 25 283
74 3 26 349
75 3 27 377
76 3 28 458
77 3 29 458
78 3 30 588
79 3 31 588
80 3 32 693
81 3 33 739
82 3 34 859
83 3 35 880
84 3 36 1061
85 3 37 1061
86 3 38 1214
87 3 39 1281
88 3 40 1470
89 3 41 1470
90 3 42 1732
91 3 43 1732
92 3 44 1945
93 3 45 2063
94 3 46 2294
95 3 47 2294
96 3 48 2631
97 3 49 2646
98 3 50 2952

 

posted on 2012-04-30 13:54  pcoda  阅读(453)  评论(0编辑  收藏  举报