智力题

作者: 一酷到底 | 来源:发表于2019-05-14 09:35 被阅读0次

我能赢吗

输入:
maxChoosableInteger = 10
desiredTotal = 11
输出:
false
思路:我们首先来看如果给定的数字范围大于等于目标值的话,直接返回true。如果给定的数字总和小于目标值的话,说明谁也没法赢,返回false。然后我们进入递归函数,首先我们查找当前情况是否在哈希表中存在,有的话直接返回即可。我们使用一个整型数按位来记录数组中的某个数字是否使用过,我们遍历所有数字,将该数字对应的mask算出来,如果其和used相与为0的话,说明该数字没有使用过,我们看如果此时的目标值小于等于当前数字,说明已经赢了,或者我们调用递归函数,如果返回false,说明也是第一个人赢了。为啥呢,因为当前我们已经选过数字了,此时就该对第二个人调用递归函数,只有他的结果是false,我们才能赢,所以此时我们标记true,返回true。如果遍历完所有数字,我们标记false,返回false

class Solution {
public:
    bool canIWin(int maxChoosableInteger, int desiredTotal) {
        if (maxChoosableInteger >= desiredTotal) return true;
        if (maxChoosableInteger * (maxChoosableInteger + 1) / 2 < desiredTotal) return false;
        unordered_map<int, bool> m;
        return canWin(maxChoosableInteger, desiredTotal, 0, m);
    }
    bool canWin(int length, int total, int used, unordered_map<int, bool>& m) {
        if (m.count(used)) return m[used];
        for (int i = 0; i < length; ++i) {
            int cur = (1 << i);   //表示将1左移i位,1,2,4,8...
            if ((cur & used) == 0) {
                if (total <= i + 1 || !canWin(length, total - (i + 1), cur | used, m)) {
                    m[used] = true;
                    return true;
                }
            }
        }
        m[used] = false;
        return false;
    }
};

猜数字大小(https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/)

从1-n中选一个数,n = 10, 我选择了8.
第一轮: 你猜我选择的数字是5,我会告诉你,我的数字更大一些,然后你需要支付5块。
第二轮: 你猜是7,我告诉你,我的数字更大一些,你支付7块。
第三轮: 你猜是9,我告诉你,我的数字更小一些,你支付9块。
游戏结束。8 就是我选的数字。
你最终要支付 5 + 7 + 9 = 21 块钱。
给定 n ≥ 1,计算你至少需要拥有多少现金才能确保你能赢得这个游戏。
思路
dp[i][j]表示从[i,j]中猜出正确数字所需要的最少花费金额.(dp[i][i] = 0)
假设在范围[i,j]中选择x, 则选择x的最少花费金额为: max(dp[i][x-1], dp[x+1][j]) + x
用max的原因是我们要计算最坏反馈情况下的最少花费金额(选了x之后, 正确数字落在花费更高的那侧)

    初始化为(n+2)*(n+2)数组的原因: 处理边界情况更加容易, 例如对于求解dp[1][n]时x如果等于1, 需要考虑dp[0][1](0不可能出现, dp[0][n]为0)
    而当x等于n时, 需要考虑dp[n+1][n+1](n+1也不可能出现, dp[n+1][n+1]为0)
    
    如何写出相应的代码更新dp矩阵, 递推式dp[i][j] = max(max(dp[i][x-1], dp[x+1][j]) + x), x~[i:j], 可以画出矩阵图协助理解, 可以发现
    dp[i][x-1]始终在dp[i][j]的左部, dp[x+1][j]始终在dp[i][j]的下部, 所以更新dp矩阵时i的次序应当遵循bottom到top的规则, j则相反, 由于
    i肯定小于等于j, 所以我们只需要遍历更新矩阵的一半即可(下半矩阵)
  public int getMoneyAmount(int n) {
        int[][] dp = new int[n+2][n+2];
        for(int i = n; i >= 1; --i) {
            for(int j = i; j <= n; ++j) {
                if(i == j)
                    dp[i][j] = 0;
                else {
                    dp[i][j] = Integer.MAX_VALUE;
                    for(int x = i; x <= j; ++x) 
                        dp[i][j] = Math.min(dp[i][j], Math.max(dp[i][x-1], dp[x+1][j]) + x);   //为什么这个地方最外面是Math.min???
                }
            }
        }
        return dp[1][n];
    }

nim游戏

你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

示例:
输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。

  bool canWinNim(int n) {
        return n%4==0?false:true;
    }

变态跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

f(1)=1, f(2)=2, f(3)=4, f(4)=8 设n+1级f(n+1),有
f(n+1) = f(1) + f(2) + ... + f(n)
f(n+2) = f(1) + f(2) + ... + f(n+1)
f(n+2)= 2f(1) + 2f(2) + ... + 2f(n)
故得f(n+2) = 2f(n+1)

矩形覆盖

我们可以用 2 * 1 的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
f(1) = 1
f(2) = 2
f(n) = f(n-1) + f(n-2)

孩子们的游戏

有n个数,从0开始编号,每次删除第m个数,下一轮循环从m+1开始。求最后剩下的数字是多少
虽然有递推公式,但是用链表模拟更好

public int LastRemaining_Solution(int n, int m) {
        LinkedList<Integer> list = new LinkedList<>();
        for(int i=0;i<n;i++)
            list.add(i);
        int a = 0;
        while(list.size() > 1)
        {
            a = (a+m-1) % list.size();
            list.remove(a);//每次删除,直到留下最后的那一个!
        }
        if(list.size() == 1)
            return list.get(0);//数组只剩下最后的一个
        return -1;
    }

n!末尾有多少个0

思路:5!=54321,0的个数和5的个数相等0

相关文章

  • 考一考(三)

    智力题5(喝汽水问题) 1元钱一瓶汽水,喝完后两个空瓶换一瓶汽水,问:你有20元钱,最多可以喝到几瓶汽水? 智力题...

  • 程序员们证明智商的时候到了!一大波智力面试题正在靠近~

    来源:网络 与传统的面试不同,程序设计面试题以程序设计题、IQ智力题及各种与计算机相关的技术性问题为主。其中智力题...

  • 考一考(二)

    智力题大考验 智力题3(燃绳问题) 烧一根不均匀的绳,从头烧到尾总共需要1个小时。现在有若干条材质相同的绳子,问如...

  • 快乐时光210530

    结束了奇迹男孩第一部分的学习,我们本周正式开始考外校智力题的学习,智力题又叫拓展题,从单词,常识,中西文化,思辨,...

  • 【智力题】

    1.【工人分金条】你让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段 ,你必须在每天结束时给他们一...

  • 智力题

    一、五个强盗抢到100个金币来分赃,强盗1提出分配方案,为了防止他分配不公,强盗们达成一致:他的方案必须有所有人(...

  • 智力题

    题目: 3升杯,5升杯各一个。没有其他容器和辅助工具,量出4升水放到5升的杯子中。 解: 1.倒满3升杯 2.3升...

  • 智力题

    两根不均匀的香,每根烧完都是一小时,有什么办法可以判断出段15分钟的时间? 答:找两根这样的香。将一根香的一头和另...

  • 智力题

    1.赛马次数 有 25 匹马和 5 条赛道,赛马过程无法计时,只能知道相对快慢。问最少需要几场赛马可以知道前 3 ...

  • 智力题

    我能赢吗 输入:maxChoosableInteger = 10desiredTotal = 11输出:false...

网友评论

      本文标题:智力题

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