uva10651-记忆化搜索

题意:给你12个字符的序列,-表示0,O表示1,那么可以进行一种变化,让你求最后最少的O是多少个。具体规则看下图

 变化规则如下,连续俩个O,可以变成一个O,a里面的7和8变成b的6。变化方向可以是左,也可以是右,比如b图内的5和6

解法:

12个字符,使用 1 << 12 记录当前的数字的1的个数。如果求过就不求了。

注意seq数组,用来判断当前位是否是1,使用mask进行位异或,比如 a图内 6 7 8 表示的是 011,掩码就是 111,011  ^ 111 = 100。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Main
{
    static Scanner scanner;

    final static int N = 13;
    final static int M = 12;
    static int number;

    // temp
    static int nums[] = new int[1 << N];

    static int[] seqTempate = { 1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, 1 << 9, 1 << 10,
            1 << 11 };

    static int min;

    public static void main(String[] args) throws FileNotFoundException
    {
        // scanner = new Scanner(System.in);
        scanner = new Scanner(new File("/Users/caicai/in"));
        int total = scanner.nextInt();
        scanner.nextLine();
        while (total != 0)
        {
            String s = scanner.nextLine();
            number = 0;
            int length = s.length();
            for (int i = 0; i < length; i++)
            {
                if (s.charAt(i) == 'o')
                {
                    number = number | (1 << i);
                }
            }
            // System.out.println(Integer.toBinaryString(number));
            // search
            init();
            dfs(number);
            System.out.println(min);
            --total;
        }
    }

    static void init()
    {
        for (int i = 0; i < (1 << N); i++)
        {
            nums[i] = Integer.MAX_VALUE;
        }
        min = Integer.MAX_VALUE;
    }

    static void dfs(int n)
    {
        if (nums[n] != Integer.MAX_VALUE)
        {
            return;
        }
        else
        {
            // check
            nums[n] = 0;
            for (int i = 0; i < 12; i++)
            {
                if ((n & seqTempate[i]) == seqTempate[i])
                {
                    ++nums[n];
                }
            }
            if (min > nums[n]) min = nums[n];
        }
        int seq1, seq2;
        for (int i = 0; i < 11; i++)
        {
            seq1 = seqTempate[i];
            seq2 = seqTempate[i + 1];
            if (((n & seq1) == seq1) && ((n & seq2) == seq2))
            {
                // seq
                // check pre and check after
                if (i == 0)
                {
                    if ((n & seqTempate[i + 2]) == seqTempate[i + 2])
                        // seq 3
                        continue;
                    // dfs after
                    dfs(n ^ 0b111);
                }
                else if (i == 10)
                {
                    // last
                    if ((n & seqTempate[i - 1]) == seqTempate[i - 1]) continue;
                    dfs(n ^ (0b111 << 9));
                }
                else
                {
                    // middle
                    // pre
                    if ((n & seqTempate[i - 1]) == 0)
                    {
                        int mask = seqTempate[i - 1] | seqTempate[i] | seqTempate[i + 1];
                        dfs(n ^ mask);
                    }
                    if ((n & seqTempate[i + 2]) == 0)
                    {
                        // after
                        int mask = seqTempate[i] | seqTempate[i + 1] | seqTempate[i + 2];
                        dfs(n ^ mask);
                    }
                }
            }
        }
    }

}

 就算找不到工作也没放弃刷题。

猜你喜欢

转载自www.cnblogs.com/shuiyonglewodezzzzz/p/11346392.html