美文网首页
2020-07-05 刷题3 模拟

2020-07-05 刷题3 模拟

作者: nowherespyfly | 来源:发表于2020-07-07 00:06 被阅读0次

60 n个骰子的点数

动态规划,dp[n,s]表示n个骰子出现s点的次数,dp[n,s]=dp[n-1,s-1]+...+dp[n-1,s-6],这只取决于n-1个骰子的点数。

class Solution {
public:
    vector<double> twoSum(int n) {
        double dp[12][70] = {0};
        dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = dp[1][5] = dp[1][6] = 1;
        for(int i = 2; i <= n; i++){
            for(int j = i; j <= 6 * i; j++){
                // dp[n][s] = dp[n-1][1]+...
                for(int k = 1; k <= 6; k++){
                    if(j > k)
                        dp[i][j] += dp[i-1][j-k];
                }
            }
        }
        double total_cnt = pow(6, n);
        vector<double> probs;
        for(int i = n; i <= 6 * n; i++){
            dp[n][i] /= total_cnt;
            probs.push_back(dp[n][i]);
        }
        return probs;
    }
};

61 扑克牌中的顺子

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        // 统计0的个数
        int zero_cnt = 0, i = 0;
        while(i < 5 && nums[i]==0){
            zero_cnt++;
            i++;
        }
        if(i >= 4)
            return true;
        // 统计空的个数
        int cur = nums[i], margin_cnt = 0;
        i++;
        while(i < 5){
            // 有相同的牌,不可能是顺子
            if(nums[i] == cur)
                return false;;
            margin_cnt += nums[i] - cur - 1;
            cur = nums[i];
            i++;
        }
        if(margin_cnt > zero_cnt)
            return false;
        return true;
    }
};

63 圆圈中最后的数字

模拟解法,用环链表实现:

class Solution {
public:
    struct ListNode{
        int val;
        ListNode* next;
        ListNode(int v): val(v), next(nullptr){}
    };
    int lastRemaining(int n, int m) {
        // construct list
        ListNode *cur = new ListNode(0);
        ListNode *head = cur;
        for(int i = 1; i < n; i++){
            cur -> next = new ListNode(i);
            cur = cur -> next;
        }
        cur -> next = head;
        ListNode *pre = cur;
        cur = cur -> next;
        // begin
        while(cur != cur -> next){
            for(int i = 1; i < m; i++){
                pre = cur;
                cur = cur -> next;
            }
            pre -> next = cur -> next;
            delete cur;
            cur = pre -> next;
        }
        return cur -> val;
    }
};

这个解法提交后过了26个case,然后就超时了,因此需要进一步优化时间。
用f(n, m)表示一共n个数,每次删除第m个数,最后剩下的数的下标,假设f(n,m)=y,f(n-1,m)=x就表示了一共n-1个数,每次删除第m个数最后剩下的数的下标。
如果n个数时,先删除一次,就剩下了n-1个数,此时,删除的这个数(也就是(m-1)%n)向后数x+1个数,就恰好是y,即:
f(n,m)=[(m-1)%n + x + 1]%n = [(m-1)%n+f(n-1,m)+1]%n
用到的定理:

  1. (a + b) % c = ((a % c) + (b % c)% c
  2. a % c % c = a % c
    最后化简得到:f(n,m) = (f(n-1,m) + m)% n
    f(1, m) = 0.
    代码:
class Solution {
public:
    int lastRemaining(int n, int m) {
        int last = 0;
        for(int i = 2; i <= n; i++)
            last = (last + m) % i;
        return last;
    }
};

真的是非常的牛皮。

相关文章

  • 2020-07-05 刷题3 模拟

    60 n个骰子的点数 动态规划,dp[n,s]表示n个骰子出现s点的次数,dp[n,s]=dp[n-1,s-1]+...

  • PTA刷题总结-Part 3 数据结构与算法

    PTA刷题总结-Part 1 基础部分PTA刷题总结-Part 2 模拟与数学问题PTA刷题总结-Part 3 数...

  • PTA刷题总结-Part 2 模拟与数学问题

    PTA刷题总结-Part 1 基础部分PTA刷题总结-Part 2 模拟与数学问题PTA刷题总结-Part 3 数...

  • 师书说阅读练习267专项刷题还是模拟刷题?

    建议上午安排2小时模拟刷题,其他时间专项刷题。 现在线上做题也方便,手机上基本随时随地都能做题。 模拟考完之后,会...

  • 自我诊断

    现在最大的问题是,刷题太少,实战模拟太少。要补齐这块。先把题量刷出来,整段时间太少,可是没办法。刷吧

  • 碎碎念|2021.10.12 晴

    1. 最近在开始刷教资的真题和模拟题。 刷题的好处就是:某些知识点,虽然背过了,但理解不到位,刷题可以帮助理解。另...

  • 模考前,我终于做到了。

    / 刷题,再看书,看了又刷题。 在第一次模拟考试前,我终于做到了自己想要达到的目标。 / 下午刷了两套,刚刚又刷了...

  • 2020-09-20-了解自己

    我可以 上周计划完成情况: 审计: 本周计划:完成模拟题1套,3套题错题讲解 课件:3套模拟题完成客观题讲解,简答...

  • 2020-11-26

    今天不是刷题就是薄荷阅读读英文,现在此时此刻我只想把题赶紧刷完然后做模拟题,好了我要去洗澡然后继续刷题然后一会儿和...

  • java刷题-3

    总结 用一个变量来控制流转 1、https://leetcode.cn/problems/fizz-buzz-mu...

网友评论

      本文标题:2020-07-05 刷题3 模拟

      本文链接:https://www.haomeiwen.com/subject/qkqvqktx.html