列表

详情


NC24671. Matchsticks

描述

Have you ever met a Matchstick math puzzle? Some of them are like this:

ADD 3 matchsticks to make the equation true. Negative numbers are not allowed and no number is greater than 9.

Well, Ramen likes such puzzles. The ACM a.k.a. All Champions Matchsticks, which is a contest about solve such puzzles, is going to hold. Ramen want to win a gold medal, so he signed up for this contest.

The subject he applies is solving puzzles about equations like the given one. The rules are pretty simple: contestants will be given some correct or incorrect Matchstick equations. The contestant can do at most one of the below actions:

- Add one matchstick into any elements.
- Remove one matchstick from any elements.

The modify should be valid, in other words, when you add or remove a matchstick, the new item should be a valid element. It will be considered solved if it comes true after making changes. Leave it not changed is also valid. Who is the first one solves all puzzles will win a gold medal, what is Ramen dreams about.

Here is a picture which shows how the numbers are placed in the contest, which may help you understand the situation better.



The puzzles are varied, and some of them are hard. Ramen knows you're good at solving these puzzles too, so he asks you for help.

输入描述

The input contains multiple test cases.

The first line contains a single integer T(1 <= T <= 1000), represents the number of test cases. 

Then T cases follow.

The first line of each test case contains two integers n(1 <= n <= 99) and p(1 <= p <= 18), represents the number of elements on the left and the right side of the equal sign.

The next 5 lines give an equation; each line contains 6(n+p)+5 characters, represents one part of the equation. There is a space between each element. In this section, each of the 5x5 rectangles forms an element.

Below gives you the corresponding Matchstick representation of the items in the order of . To make it more clear, we use dots(.) to represent spaces. In real input, no dots are included.



You can assume that the input has below guarantees:
- The equation only contains -, |, +, x and spaces.
- There will be only one equal sign in each test case.
- The operands on the left side of the equal sign will be precisely one digit each.
- The right side of the equal sign will be only and exactly one number without leading zeros.
- The result will not exceed the maximum possible value of a 64-bit integer.

输出描述

For each test case, output Case #x: y, x is the number of the test case(starts from 1), y is Yes if you can modify at most one element of the equation to make it right, otherwise No.

示例1

输入:

2
3 2
 ---  \   /  ---        |   |  --- 
|      \ /      | ----- |   | |   |
 ---    x       |        ---   --- 
    |  / \      | -----     | |   |
 ---  /   \     |           |  --- 
3 1
 ---    |    ---         --- 
|       |       | -----     |
 ---  --+--  ---         --- 
    |   |       | ----- |    
 ---    |    ---         ---

输出:

Case #1: No
Case #2: Yes

说明:

Be careful, please add the necessary spaces when you copy the sample input if there are no spaces at the end of each line. We're sorry for the inconvenience.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 347ms, 内存消耗: 604K, 提交时间: 2019-04-14 21:59:31

#include <bits/stdc++.h>

using namespace std;

#define TemplateVersion "3.4.1"
// Useful Marcos
//====================START=====================
// Compile use C++11 and above
#ifdef LOCAL
#define debug(args...)                           \
    {                                            \
        string _s = #args;                       \
        replace(_s.begin(), _s.end(), ',', ' '); \
        stringstream _ss(_s);                    \
        istream_iterator<string> _it(_ss);       \
        err(_it, args);                          \
    }
void err(istream_iterator<string> it)
{
}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args)
{
    cerr << *it << " = " << a << endl;
    err(++it, args...);
}
#define MSG cout << "Finished" << endl
#else
#define debug(args...)
#define MSG
#endif
#if __cplusplus >= 201703L
template <typename... Args>
void readln(Args &... args)
{
    ((cin >> args), ...);
}
template <typename... Args>
void writeln(Args... args)
{
    ((cout << args << " "), ...);
    cout << endl;
}
#elif __cplusplus >= 201103L
void readln()
{
}
template <typename T, typename... Args>
void readln(T &a, Args &... args)
{
    cin >> a;
    readln(args...);
}
void writeln()
{
    cout << endl;
}
template <typename T, typename... Args>
void writeln(T a, Args... args)
{
    cout << a << " ";
    writeln(args...);
}
#endif
#if __cplusplus >= 201103L
#define FOR(_i, _begin, _end) for (auto _i = _begin; _i < _end; _i++)
#define FORR(_i, _begin, _end) for (auto _i = _begin; _i > _end; _i--)
#else
#define FOR(_i, _begin, _end) for (int _i = (int)_begin; _i < (int)_end; _i++)
#define FORR(_i, _begin, _end) for (int _i = (int)_begin; _i > (int)_end; _i--)
#define nullptr NULL
#endif
#if __cplusplus >= 201103L
#define VIS(_kind, _name, _size) \
    vector<_kind> _name(_size);  \
    for (auto &i : _name)        \
        cin >> i;
#else
#define VIS(_kind, _name, _size)    \
    vector<_kind> _name;            \
    _name.resize(_size);            \
    for (int i = 0; i < _size; i++) \
        cin >> _name[i];
#endif
// alias
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define tcase() \
    int T;      \
    cin >> T;   \
    FOR(kase, 1, T + 1)
// Swap max/min
template <typename T>
bool smax(T &a, const T &b)
{
    if (a > b)
        return false;
    a = b;
    return true;
}
template <typename T>
bool smin(T &a, const T &b)
{
    if (a < b)
        return false;
    a = b;
    return true;
}
// ceil divide
template <typename T>
T cd(T a, T b)
{
    return (a + b - 1) / b;
}
// min exchange
template <typename T>
bool se(T &a, T &b)
{
    if (a < b)
        return false;
    swap(a, b);
    return true;
}
// A better MAX choice
const int INF = 0x3f3f3f3f;
const long long INFLL = 0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef set<int> si;
typedef vector<string> cb;
//====================END=====================

// Constants here
map<string, int> table;
string components[] = {" --- ", "|   |", "    |", "|    "};
string numbers[][5] = {
    {components[0], components[1], components[1], components[1], components[0]},
    {components[2], components[2], components[2], components[2], components[2]},
    {components[0], components[2], components[0], components[3], components[0]},
    {components[0], components[2], components[0], components[2], components[0]},
    {components[1], components[1], components[0], components[2], components[2]},
    {components[0], components[3], components[0], components[2], components[0]},
    {components[0], components[3], components[0], components[1], components[0]},
    {components[0], components[2], components[2], components[2], components[2]},
    {components[0], components[1], components[0], components[1], components[0]},
    {components[0], components[1], components[0], components[2], components[0]}};

string operators[][5] = {
    {"  |  ", "  |  ", "--+--", "  |  ", "  |  "},
    {"     ", "     ", "-----", "     ", "     "},
    {"\\   /", " \\ / ", "  x  ", " / \\ ", "/   \\"},
    {"     ", "-----", "     ", "-----", "     "}};

vector<int> trans[] = {
    {8},       // 0
    {7},       // 1
    {},        // 2
    {9},       // 3
    {},        // 4
    {9, 6},    // 5
    {5, 8},    // 6
    {1},       // 7
    {0, 6, 9}, // 8
    {5, 3, 8}, // 9
    {11},      // 10, +
    {10},      // 11, -
    {},        // 12, *
    {},        // 13, =
};

vi l, r;

// Pre-Build Function
inline void build()
{
    for (int i = 0; i < 10; i++)
    {
        string s = "";
        for (auto it : numbers[i])
            s += it;
        table[s] = i;
    }

    for (int i = 0; i < 4; i++)
    {
        string s = "";
        for (auto it : operators[i])
            s += it;
        table[s] = i + 10;
    }
}

int pre(int op)
{
    if (op == 12)
        return 2;
    return 1;
}

ll getVal(vector<int> v)
{
    ll ret = 0;
    int n = v.size();
    bool flag = false;

    int i = 0;

    if (v[i] == 11)
        flag = true, i++;
    else if (v[i] == 10)
        i++;

    for (; i < n; i++)
    {
        ret *= 10LL;
        ret += v[i];
    }

    return flag ? -ret : ret;
}

ll eval(vector<int> v)
{
    stack<int> ops;
    queue<int> rpn;
    for (const auto &i : v)
    {
        if (0 <= i && i <= 9)
            rpn.push(i);
        else
        {
            while (ops.size() && pre(ops.top()) >= pre(i))
            {
                rpn.push(ops.top());
                ops.pop();
            }
            ops.push(i);
        }
    }

    while (ops.size())
    {
        rpn.push(ops.top());
        ops.pop();
    }

    stack<ll> s;

    while (rpn.size())
    {
        int token = rpn.front();
        rpn.pop();

        if (token == 10)
        {
            ll t = s.top();
            s.pop();
            t += s.top();
            s.pop();
            s.push(t);
        }
        else if (token == 11)
        {
            ll t = s.top();
            s.pop();
            t = s.top() - t;
            s.pop();
            s.push(t);
        }
        else if (token == 12)
        {
            ll t = s.top();
            s.pop();
            t *= s.top();
            s.pop();
            s.push(t);
        }
        else
            s.push(token);
    }

    return s.top();
}

bool check(int n, int p)
{
    if (eval(l) == getVal(r))
        return true;

    for (int i = 0; i < n; i++)
    {
        int k = l[i];

        for (const auto &it : trans[k])
        {
            l[i] = it;
            if (eval(l) == getVal(r))
                return true;
        }

        l[i] = k;
    }

    for (int i = 0; i < p; i++)
    {
        int k = r[i];

        for (const auto &it : trans[k])
        {
            r[i] = it;
            if (eval(l) == getVal(r))
                return true;
        }

        r[i] = k;
    }

    return false;
}

void parseEquation(int n, int p, vector<string> &v)
{
    l.clear();
    r.clear();

    for (int i = 0; i < n; i++)
    {
        string elem = "";
        for (int idx = 0; idx < 5; idx++)
            elem += v[idx].substr(6 * i, 5);
        l.pb(table[elem]);
    }

    for (int i = n + 1; i < n + p + 1; i++)
    {
        string elem = "";
        for (int idx = 0; idx < 5; idx++)
            elem += v[idx].substr(6 * i, 5);
        r.pb(table[elem]);
    }
}

// Actual Solver
inline void solve()
{
    tcase()
    {
        cout << "Case #" << kase << ": ";
        int n, p;
        cin >> n >> p;
        vector<string> v(5);
        cin.get();
        for (auto &i : v)
            getline(cin, i);

        parseEquation(n, p, v);

        if (check(n, p))
            cout << "Yes\n";
        else
            cout << "No\n";
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

#ifdef LOCAL
    clock_t _begin = clock();
#endif

    build();
    solve();

#ifdef LOCAL
    cerr << "Time elapsed: " << (double)(clock() - _begin) * 1000 / CLOCKS_PER_SEC << "ms." << endl;
#endif

    return 0;
}

上一题