Write algorithm problem with Python - Los Valley P1149 matchstick equation

topic

Source title

P1149 matchstick equation, https://www.luogu.org/problem/P1149

Title Description

You matchsticks n, the number of the form "A + B = C" can you spell the equation? Equation A, B, C is an integer with a match stick spell (if the number of non-zero, then is not the most significant bit 00). Fight of 0-90-9 with spelling matchstick shown:

note:

  1. Plus their needs and equal sign two matchsticks
  2. If A ≠ B, then A + B = C and B + A = C as different equations (A, B, C> = 0)
  3. n matchsticks must all spend

Input Format

An integer n (n <= 24).

Output Format

An integer number of different equations could spell.

Sample input and output

Example 1:

输入

14

输出

2

Sample 2

输入

18

输出

9

solution

Method 1: table method to fight violence

Because the maximum value of n is only 24, you can advance to answer directly out exhaustive.

# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]


# 输入一个数,计算需要多少火柴棒
def count(x):
    if x == 0:
        return 6
    c = 0
    while x > 0:
        digit = x % 10
        c += num[digit]
        x = x // 10
    return c


result = [0] * 24

for n in range(10, 25): #10根火柴以下都是0,很明显
    print("caculate ", n)
    for i in range(0, 10000): #假设单个数字最大值为10000
        for j in range(0, 10000):
            if count(i) + count(j) + count(i+j) == n - 4:
                result[n-1] += 1
print(result)

The code on my computer ran for a long time can not get out, the maximum value can be changed to 2000. The same code in Java and soon the results sufficient to show that Python is not suitable for this type of problem.

public class Test {
    public static void main(String[] args) {
        int[] result = new int[24];
        for(int i = 10; i <= 24; i++) {
            for(int j = 0; j < 10000; j++) {
                for(int k = 0; k < 10000; k++) {
                    if(count(j) + count(k) + count(j+k) == i - 4) {
                        result[i] += 1;
                    }
                }
            }
        }
        for(int i = 0; i < 24; i++) {
            System.out.println(result[i]);
        }

    }
    public static int[] num = {6,2,5,5,4,5,6,3,7,6};
    public static int count(int x) {
        if(x == 0) {
            return 6;
        }
        int c = 0;
        while (x > 0) {
            int digit = x % 10;
            c += num[digit];
            x = x / 10;
        }
        return c;
    }
}

The end result is {0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,8,9,6,9,29,39,38,65, 88,128}.

But although violence is exhaustive, but there is a problem in the code above, repeated calls to count every time, save up early to count on the line, although in Python is still very slow, but the results can be within an acceptable time.

# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]


# 输入一个数,计算需要多少火柴棒
def count(x):
    if x == 0:
        return 6
    c = 0
    while x > 0:
        digit = x % 10
        c += num[digit]
        x = x // 10
    return c


COUNT = [0] * 20000
for i in range(0, 20000):
    COUNT[i] = count(i)

result = [0] * 24

for n in range(10, 25):
    print("caculate ", n)
    for i in range(0, 10000):
        for j in range(0, 10000):
            if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4:
                result[n-1] += 1
print(result)

Method 2: Optimization of the methods described above

There is no better way, we can minimize the number of cycles, in addition, to know if the maximum number of single, it would be better to do.

To spell out the largest number with a minimum of a match stick, and that priority must spell out the maximum number of digits, because certainly better than 999 small 1111, because a number of at least two matches, so for an even number of matches, must be used to fight 11111 such as the maximum, for example 10 matches, the maximum number can spell 11111,20 is a match, can spell the maximum number is 1111111111.

Assuming a maximum value of more than 10,000, and that at least 10, can spell 11111, the remaining 10 + 8 divided into two, two pooled impossible exceeds 10000, it does not exceed the maximum value of 10000.

Assuming that the maximum may be located [9000,10000), at least 12, can spell 9111, the remaining 8 can not add up to this number.

Assuming that the maximum may be located [8000,9000), at least 13, more impossible.

Assuming that the maximum may be located in [7000, 8000), at least 9, i.e. 7111, into the remaining 11 9 + 2,2 ,, if only one root, it makes up 9 to be 7110, the number is not enough.

Assuming that the maximum may be located in [6000, 7000), at least 12, nor the remaining eight.

Assuming that the maximum may be located in [5000, 6000), at least 11, maximum remaining 4 digits 9 can spell the 7xxx or 1xxx, can not add up to 5000. The same goes for [2000, 5000).

Assuming that the maximum may be located in [1900, 2000], it requires a minimum 12, 1911, the rest can not add up to 1911.

In turn, we find that the maximum number can not be greater than 1111. By a program results, the maximum value is 712.

After improvement, do not hit the table can be AC.


# 0-9需要多少根火柴棒
num =[6, 2, 5, 5, 4, 5, 6, 3, 7, 6]


# 输入一个数,计算需要多少火柴棒
def count(x):
    if x == 0:
        return 6
    c = 0
    while x > 0:
        digit = x % 10
        c += num[digit]
        x = x // 10
    return c


COUNT = [0] * 713
for i in range(0, 713):
    COUNT[i] = count(i)

result = 0

n = int(input())

for i in range(0, 712):
    for j in range(0, 712):
        if i + j > 712:
            continue
        if COUNT[i] + COUNT[j] + COUNT[i+j] == n - 4:
            result += 1

print(result)

Guess you like

Origin www.cnblogs.com/nxlhero/p/11691957.html
Recommended