zoukankan      html  css  js  c++  java
  • The secret code

    The secret code

    Input file: stdinOutput file: stTime limit: 1 sec

    Memory limit: 256 Mb
    After returning from the trip, Alex was unpleasantly surprised: his porch door had a new combination lock. Alex
    can not get into his house! Code lock contains N disks, each of which can be in one of M positions. There
    is only one correct position. Alex thoroughly inspected discs and by fingerprints and scratches determined the
    probability of each position for each disk. Now Alex has K attempts to guess the correct code: if he fails, his
    vigilant neighbors will call the police, and Alex will have a hard time persuading cops that he is not a thief, but
    tried to get home. Help Alex to calculate the maximum probability of getting home, not to the police.
    Limit
    1 ≤ N ≤ 100
    1 ≤ M ≤ 20
    1 ≤ K ≤ 100
    0 ≤ P ij ≤ 100
    Input
    The first line of input file contains three integers: N, M Рё K.
    Next N lines contain M integers each: j-th number of the i-th line (P ij ) — the probability of a situation where
    i-th disc’s correct position is j. Given that
    P M
    j=1 P ij
    = 100.
    Output
    Print a single number — Alex’s chances to guess the correct code in time. Output result should have an absolute
    percentage error not grater than 10 −7 .
    Example
    stdin

    2 2 1
    50 50
    10 90
    3 5 4
    10 15 20 25 30
    1 2 3 4 90
    100 0 0 0 0

    stdout

    0.45
    0.81

    题目大意:

       n个数列,每个数列取一个数,得到这些数的乘积,求前k个最大的乘积。

    多谢syx的指导!

    解题思路:

      对每个数列排序后。

      首先,第一大的自然是所有数列最大值乘积。

      接着,将最大乘积加到ans上,然后将这个乘积能够达到的所有下一个状态均加入优先队列中。至于保存状态,每个状态只需保存其在每个数列的取到第几个数的指针即可,显然下一个状态是在该状态之后,并且出现在某一个指针向后移位。故将所有下一个状态加入优先队列。

      然后,当找到第k个或者是空队列时退出循环,否则返回上一步。

      最后,输出答案。

    实现方法,直接使用STL中的priority_queue,若数据量加大,可惜优先队列不能删除尾节点,不过可利用最大最小堆保存前k个即可。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <utility>
    #include <stack>
    #include <queue>
    #include <map>
    #include <deque>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    
    using namespace std;
    
    struct State{
        int head[105];
        double x;
        bool operator<(const State &b) const
        {
            return x<b.x;
        }
    };
    
    double a[105][21];
    int n,m,k;
    priority_queue<State> q;
    bool cmp(double x, double y)
    {
        return x>y;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                scanf("%lf",&a[i][j]);
                a[i][j]/=100;
            }
            sort(a[i],a[i]+m,cmp);
        }
    
        State tmp;
        tmp.x=1.0;
        for(int i=0; i<n; i++)
        {
            tmp.head[i]=0;
            tmp.x*=a[i][0];
        }
        q.push(tmp);
    
        double ans=0.0;
        for(int i=0; i<k&&!q.empty(); i++)
        {
            tmp=q.top();
            q.pop();
            ans+=tmp.x;
            for(int j=0; j<n; j++)
                if(tmp.head[j]<m-1) 
                {
                    if(a[j][tmp.head[j]+1]==0) continue;
                    tmp.x=tmp.x / a[j][tmp.head[j]] * a[j][tmp.head[j]+1];
                    tmp.head[j]++;
                    q.push(tmp);
                    tmp.x=tmp.x / a[j][tmp.head[j]] * a[j][tmp.head[j]-1];
                    tmp.head[j]--;
                }
        }
    
        printf("%.8f
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    素数算法问题
    字符指针和字符数组
    指针引用多维数组
    指针细节整理3
    指针细节整理2
    指针细节整理
    公约数和公倍数
    冒泡排序、选择排序
    如何写出高性能的sql语句?
    并发控制
  • 原文地址:https://www.cnblogs.com/Mathics/p/3906139.html
Copyright © 2011-2022 走看看