一战通offer第四题解法

题意是由A先选珠子,让B去串,问A至少选几个蓝珠子一定能赢。

我们把珠子从0...n-1编号。

下面所有加减法都默认取模了。

如果A选了x号点,那么如果x-(n/2-1)或x+(n/2-1)是蓝色的,就一定能把项链分成一部分是(n+1)/2的。

那我们把x和那两个点连线,对于整个图都这么做就能画出一个图形(n=5是五角星)(n=7是七芒星)。

我们换个问题,A最多选几个蓝色的点使得 一定存在A输的情况 。加一就是原题答案。

现在问题变成如何选出最多的点使得没有两个点是有边相连的(有相连的A就能赢)。

如果我们按我们画出来的图去串项链,那么就变成一串(或者几串)新的项链,而且问题就变成了如何选点使得这个(些)新的项链上没有相邻两个点被同时选中。显然是选一个空一个这样去选能选出最多的。


所以最后问题变成了,把原来的项链分解成几个不相交的部分,每一个部分选出最多的点,加起来就是最多能选多少个蓝色的点使得一定存在A输的情况。加一就是原题的答案。

至于怎么找这些不相交的部分,用循环暴力找就行。
public class Chain {

    public int findK(int n) {
        boolean[] vis = new boolean[n];
        int step = n / 2 - 1;
        int ans = 0;
        for (int i = 0; i < n; i++) vis[i] = false;
        for (int i = 0; i < n; i++) {
            if (!vis[i]) ans += findCircle(i, step, n, vis);
        }
        ans++;
        return ans;
    }


    int findCircle(int i, int step, int n, boolean[] vis) {
        int cnt = 0;
        while (!vis[i]) {
            vis[i] = true;
            cnt++;
            i = (i + step) % n;
        }
        return cnt / 2;
    }

    public static void main(String[] args) {
        Chain c = new Chain();
        System.out.println(c.findK(5));
        System.out.println(c.findK(7));
        System.out.println(c.findK(9));
    }

}

全部评论
class Chain { public:     int findK(int n) {         if(n%3==0) return n/2;         return (n+1)/2;     } }; 刚才找规律竟然过了。。。
点赞 回复 分享
发布于 2016-04-19 22:29
考完之后想出来了……只花了思路的图,没写代码
点赞 回复 分享
发布于 2016-04-19 22:21
厉害厉害!!
点赞 回复 分享
发布于 2016-04-20 15:14
膜拜,大牛,你真是太厉害了
点赞 回复 分享
发布于 2016-04-20 14:29
膜拜
点赞 回复 分享
发布于 2016-04-19 22:15

相关推荐

哞客37422655...:github如果提交不是很多 可以不写 可能会是减分项。之前听别人讲过的
点赞 评论 收藏
分享
01-03 19:22
宁夏大学 运营
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务