zoukankan      html  css  js  c++  java
  • leetcode 第 29 场双周赛

    直接暴力做法,排序之后去掉最大最小就行
    线性做法应该就直接记录最大最小,但是没必要


    class Solution {
    public:
        double average(vector<int>& a) {
            sort(a.begin(), a.end());
            double ans = 0;
            for(auto e:a)
                ans += e;
            ans -= a[0];
            ans -= a.back();
            return ans/(a.size()-2);
        }
    };
    

    手速场就是舒服,直接O(sqrt(N))求因子,然后排序一下输出

    class Solution {
    public:
        int kthFactor(int n, int k) {
            vector<int> ans;
            for(int i=1; i*i<=n; i++){
                if(n%i==0){
                   ans.push_back(i);
                if(i*i!=n)
                    ans.push_back(n/i);
                        
                }
            }
            sort(ans.begin(), ans.end());
            return ans.size()<k?-1:ans[k-1];
        }
    };
    

    记录前缀和后缀的1的个数,貌似写复杂了
    双指针应该可以更快而且节省空间

    class Solution {
    public:
        int longestSubarray(vector<int>& a) {
            vector<int> b(a.size()+5, 0), c(a.size()+5, 0);
            for(int i=0; i<a.size(); i++){
                if(a[i]==1)
                    b[i+1]=b[i]+1;
                else{
                   b[i+1]=0;
                }
            }
             for(int i=a.size()-1; i>=0; i--){
                if(a[i]==1)
                    c[i]=c[i+1]+1;
                else{
                   c[i]=0;
                }
            }
            int ans=0;
            for(int i=0; i<a.size(); i++){
                ans = max(ans, b[i]+c[i+1]);
            }
            return ans;
        }
    };
    

    这道题,虽然过了但是很羞愧,用的是个假算法


    假算法
    1. 求每个节点的出度的大小
    2. 对图利用优先队列进行一波拓扑排序
    但是这个贪心策略是有问题的,在面对出度相同的时候
    而且节点可选个数多于k时,会出现错误


    struct Node{
        int no;
        int child;
        Node(){
            no=0;
            child=0;
        }
        friend bool operator<(const Node& a,const  Node& b){
            return a.child<b.child;
        }
    };
    
    class Solution {
    public:
        int minNumberOfSemesters(int n, vector<vector<int>>& dep, int k) {
            priority_queue<Node> pq;
            Node no[16];
            vector<int> in(n+1, 0);
            for(int i=0; i<16; i++)
                no[i].no=i;
            vector<vector<int>> G(n+1, vector<int>(0));
            for(auto e:dep){
                in[e[1]]++;
                no[e[0]].child += 1;
                G[e[0]].push_back(e[1]);
            }
            int ans = 0;
            for(int i=1; i<=n; i++){
                if(in[i]==0)
                    pq.push(no[i]);
            }
            vector<int> temp;
            cout<<pq.size()<<endl;
            while(!pq.empty()){
                cout<<ans<<endl;
                ans++;
                temp.clear();
                int cnt=0;
                while(!pq.empty()&&cnt<k){
                    cnt++;
                    Node te = pq.top();
                    pq.pop();
                    for(auto i:G[te.no]){
                        in[i]--;
                        if(in[i]==0)
                            temp.push_back(i);
                    }
                }
                for(auto i:temp)
                    pq.push(no[i]);
            }
            return ans;
        }
    };
    

    正确的做法
    状压dp, 课程用一个整数的二进制位表示
    则dp[i|chose] = min(dp[i|chose], dp[i]+1)
    其中i表示当前已经修过的课
    chose表示下一个学期可以修的课


    class Solution {
        public final int INT_MAX = 101;
        public int[] dp =null;  //dp数组
        public int minNumberOfSemesters(int n, int[][] dependencies, int k) {
            dp = new int[1<<n];
            for(int i=0; i<1<<n; i++)
                dp[i] = INT_MAX;
            dp[0]=0;
            for(int[] e:dependencies){
                e[0] -= 1;
                e[1] -= 1;
            }
            
            for(int i=0; i<1<<n; i++){
                int unable=0;
                for(int[] e:dependencies){
                    if((i>>e[0]&1)==0)
                        unable |= 1<<e[1];
                }
                int can = 0;
                for(int j=0; j<n; j++){
                    if((unable>>j&1)==0&&(i>>j&1)==0)
                        can |= 1<<j;
                }
                dfs(n, k, i, can, 0, 0);
            }
            return dp[(1<<n)-1];
        }
        public void dfs(int n, int k, int i, int can, int chosed, int start){
            if(k==0||can==0){
                dp[i|chosed] = Math.min(dp[i|chosed], dp[i]+1);
                return;
            }
            for(int j=start; j<n; j++){
                if((i>>j&1)==0 && (can>>j&1)==1)
                    dfs(n, k-1, i, can-(1<<j), chosed+(1<<j), j+1);
            }
        }
    }
    
  • 相关阅读:
    C# 单例模式
    [C# 线程处理系列]专题四:线程同步
    C#实现远程开机(局域网测试通过)
    C#实现类只实例化一次(被多个类访问调用)
    c#委托与事件、消息、WndProc用法(转)
    UML 类图常用表示方法.
    C# Socket 接受数据不全的处理
    执行数据库操作失败: 连接未关闭。 连接的当前状态为打开
    hdu 2018 母牛的故事 动态规划入门题
    Codeforces 1029B. Creating the Contest 动态规划O(nlogn)解法 及 单调队列O(n)解法
  • 原文地址:https://www.cnblogs.com/Crossea/p/13201519.html
Copyright © 2011-2022 走看看