pe209

https://projecteuler.net/problem=209

求有多少种真值表,满足满足任意给定的六元组都满足下面的式子

解析:

注意到式子之间是and,也就是说要满足对六元组(a, b, c, d, e, f)转为(b, c, d, e, f, a xor (b and c))后,至少一个真值表对应数为0,

然后对(b, c, d, e, f, a xor (b and c))再转换后的结果,也要满足这个条件。

 

因此我们可以求出在有多少个环,每个环内的六元祖要满足,相邻的两个数字不能同时为1,这个简单打表计算 ,其实可以发现实际上是个lucas数列。

 

附上代码:



import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by dezhonger on 2019/10/01
 *
 * @author dezhonger
 * @since 2019/10/01
 */
public class PE209 {

    public static void main(String[] args) {
        new PE209().run();
    }


    List<List<Integer>> lists = new ArrayList<>();
    Set<Integer> set = new HashSet<>();

    void run() {
        for (int a = 0; a < 2; a++)
            for (int b = 0; b < 2; b++)
                for (int c = 0; c < 2; c++)
                    for (int d = 0; d < 2; d++)
                        for (int e = 0; e < 2; e++)
                            for (int f = 0; f < 2; f++) {
                                int cur = a * 1 + b * 10 + c * 100 + d * 1000 + e * 10000 + f * 10_0000;
                                int dur = cur;
                                if (!set.contains(cur)) {
                                    List<Integer> tmp = new ArrayList<>();
                                    tmp.add(cur);
                                    while (true) {
                                        int nxt = run(cur);
                                        if (nxt != dur) {
                                            tmp.add(nxt);
                                            cur = nxt;
                                        } else {
                                            break;
                                        }
                                    }
                                    set.addAll(tmp);
                                    lists.add(tmp);
                                }
                            }

        //http://oeis.org/A000032
        long[] lucas = new long[50];
        lucas[1] = 1;
        lucas[2] = 3;
        lucas[3] = 4;
        for (int i = 4; i < lucas.length; i++) lucas[i] = lucas[i - 1] + lucas[i - 2];
        long res = 1L;
        for (int i = 0; i < lists.size(); i++) {
            int size = lists.get(i).size();
            res = res * lucas[size];

        }
        System.out.println(res);
    }


    int[] f(int x) {
        int[] a = new int[6];
        int index = 5;
        while (x > 0) {
            a[index--] = x % 10;
            x /= 10;
        }
        return a;
    }

    int run(int o) {
        int[] t = f(o);
        int a, b, c, d, e, f;
        a = t[0];
        b = t[1];
        c = t[2];
        d = t[3];
        e = t[4];
        f = t[5];
        int x = b * c;
        x = (a + x) % 2;
        return f * 10 + e * 100 + d * 1000 + c * 10000 + b * 10_0000 + x ;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值