Loading

2023.8.2 翻转卡片游戏

image

坑点注意:x不能与任意一张卡片的正面数字相同,包括自己。因此如果一张卡片正反面数字相同,必然不可能是x。

暴力

由于\(n \leq 1000\),因此\(n^2\)暴力是可以过的。遍历每一个\(nums[i]\),判断其正反面是否相同,相同则跳过,不相同则进一步检验。分为两种情况,一是取\(fronts[i]\),另一种是取\(backs[i]\)。检验其他卡片是否至少有一面不同,如果没有,则不能选为x。如果通过,则与答案取一个min。

集合

建立一个set,事先遍历所有的\(nums[i]\),将所有正反面相同的卡片加入到set中。
正反面相同的卡片,无论如何翻转,都不会改变。而正反面不同的卡片,如果一面数字相同了,我们可以翻转到另一面。

  • 取卡片的正面的情况。遍历所有卡片,判断set中是否存在与\(fronts[i]\)相同的key,如果不存在,说明正面没有数字与它相同,可以选为x,更新答案。
  • 取卡片的反面的情况。遍历所有卡片,判断set中是否存在与\(backs[i]\)相同的key,如果不存在,说明正面同样也没数字与它相同,可以选为x,更新答案。

假设现在有一个卡片1,其正面值为x,反面值为z。而其他卡片中存在一个卡片2其正面值为x,而反面值为y,那么这个卡片是不会被加入到set中的,也就是说x和y必然是不同的。卡片1取正面值时,可以翻转卡片2得到贡献。卡片1取反面值时,可以翻转卡片2也可以不翻转,都也可以得到贡献。

class Solution {
public:
    int flipgame(vector<int>& fronts, vector<int>& backs) 
    {
        int n = fronts.size();
        int res = 0x3f3f3f3f;

        unordered_set<int> s;
        for (int i = 0; i < n; ++i)
        {
            if (fronts[i] == backs[i]) s.insert(fronts[i]);
        }

        for (int x : fronts)
        {
            if (x < res && !s.count(x)) 
                res = x;
        }
        for (int x : backs)
        {
            if (x < res && !s.count(x))
                res = x;
        }
        return res == 0x3f3f3f3f ? 0 : res;
    }
};
posted @ 2023-08-03 11:23  烤肉kr  阅读(13)  评论(0编辑  收藏  举报