zoukankan      html  css  js  c++  java
  • xcoj1009-密码

    1009: 密码题目地址
    时间限制: 1 Sec 内存限制: 64 MB

    题目描述
    小翔同学的宿舍WIFI添加了密码,密码每天都会变更。而小翔每天都会给蹭网的同学们提供密码提示。现在请你根据密码提示,编写程序破译密码。
    已知密码提示给出了n个整数 a1,a2,…,an,以及一个整数 t(t小于n)。从这n个整数中任选t个相加,可分别得到一系列的和。例如当 n=4,t=3,4 个整数分别为 3,7,12,19 时,可得全部组合的和分别为:
    3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34。
    而和为素数的个数即为小翔宿舍WIFI的密码。
    例如上例,只有一种的和为素数:3+7+19=29,于是密码即为1。
    输入
    n , t (1<=n<=20,t<n)
    a1,a2,…,an (1<=ai<=5000000)

    输出
    一个整数(即为密码)。
    样例输入
    4 3
    3 7 12 19
    样例输出
    1

    思路:本题首先打表产生素数;然后再递归产生组合数,即n个数中选取t个数,然后将产生的组合数相加根据素数表验证是否为素数,并统计结果

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <fstream>
    using namespace std;
    
    int prime[100005];  //素数表
    int data[21];
    int cnt, t;
    
    void getPrime()  //产生素数表
    {
        prime[1] = false;
        int sq = sqrt(100005+0.5);
        for(int i = 2; i <= sq; i ++)
        {
            if(!prime[i])
            {
                continue;
            }
            for(int j = i + i; j < 100005; j += i)
            {
                prime[j] = false;
            }
        }
    }
    
    void f(int c[], int t) //统计结果
    {
        long sum = 0;
        for(int i = 0; i < t; i ++)
        {
            sum += c[i];
            //cout << c[i] << "  ";
        }
        //cout << sum << endl;
        if(prime[sum])
        {
            cnt ++;
        }
    }
    
    //产生组合数,arr为原始数组,n为数组的个数,c为储存组合数数组,t为选取数的个数,i为当前选取的数组的位置,num为当前剩余需要选的数字个数
    void com(int arr[], int n, int c[], int t, int i, int num)
    {
        if(num == 0)
        {
            f(c, t);
        }
        else
        {
            for(int j = i; j < n-num+1; j ++)
            {
                c[t-num] = arr[j];
                //cout << arr[j] << " " << c[t-num] << endl; 
                com(arr, n, c, t, j+1, num-1);
            }
        }
    }
    
    int main()
    {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        //ifstream cin("data.in");
        memset(prime, true, sizeof(prime));
        getPrime();
        int n;
        while(cin >> n)
        {
            cin >> t;
            int c[21];
            cnt = 0;
            for(int i = 0; i < n; i ++)
            {
                cin >> data[i];
                //cout << data[i] << endl;
            }
            com(data, n, c, t, 0, t);
            cout << cnt << endl;
        }
        return 0;
    }
  • 相关阅读:
    Cesium加载Geoserver wtms服务和wms服务
    使用GeoServer+PostgreSQL+PostGIS+OpenLayers3
    Cesium 绕点旋转飞行效果
    时间分片技术(解决 js 长任务导致的页面卡顿)
    Cesium随笔:视锥绘制(下)
    使用geoserver发布arcgis切片
    Cesium点击获取模型或者地形点的位置
    npm库使用roullup封装经验总结
    一个删除node_modules文件夹的脚本
    cesium点击面高亮事件
  • 原文地址:https://www.cnblogs.com/topk/p/6580114.html
Copyright © 2011-2022 走看看