Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

ปริศนาคณิตศาสตร์ตัวอักษร (Verbal Arithmetic) ใน C++


คำอธิบายโจทย์

สมการคำพูด: words ด้านซ้าย + ... = result ด้านขวา แมปตัวอักษรเป็นตัวเลข 0-9 ตัวต่างต้องต่างตัวเลข ห้าม leading zero ตรวจสอบว่ามีคำตอบหรือไม่

ตัวอย่าง

words = ["SEND","MORE"], result = "MONEY" → True

แมป: S=9, E=5, N=6, D=7, M=1, O=0, R=8, Y=2 → 9567+1085=10652

วิธีแก้ปัญหา

Backtracking คอลัมน์ต่อคอลัมน์ (จากหลักหน่วยขึ้นไป):

  • i2c[10]: digit → char, c2i[26]: char → digit
  • solve(idx, l, sum): idx=word index, l=column, sum=ผลรวมคอลัมน์นี้
  • ประมวลผลคอลัมน์ l ของทุก word บวก sum
  • ที่ result[l]: ตรวจสอบ sum%10 ตรงหรือแมปใหม่ได้
  • Carry = sum/10 ไปคอลัมน์ถัดไป

การทำงานของโค้ด

#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    char i2c[10];
    int c2i[26];
    vector<string> w;
    string r;
    
    bool solve(int idx, int l, int sum) {
        if(l == r.size()) return sum == 0;
        if(idx == w.size()) {
            if(c2i[r[l]-'A'] != -1) {
                if(c2i[r[l]-'A'] == sum%10) return solve(0, l+1, sum/10);
            } else if(i2c[sum%10] == -1) {
                if(l == r.size()-1 && sum%10 == 0) return false;
                c2i[r[l]-'A'] = sum%10;
                i2c[sum%10] = r[l]-'A';
                bool temp = solve(0, l+1, sum/10);
                c2i[r[l]-'A'] = -1; i2c[sum%10] = -1;
                return temp;
            }
            return false;
        }
        if(l >= w[idx].size()) return solve(idx+1, l, sum);
        if(c2i[w[idx][l]-'A'] != -1) {
            if(l == w[idx].size()-1 && c2i[w[idx][l]-'A'] == 0) return false;
            return solve(idx+1, l, sum + c2i[w[idx][l]-'A']);
        }
        for(int i=0; i<10; i++) {
            if(i2c[i] != -1) continue;
            if(i == 0 && l == w[idx].size()-1) continue;
            i2c[i] = w[idx][l]-'A';
            c2i[w[idx][l]-'A'] = i;
            if(solve(idx+1, l, sum+i)) return true;
            i2c[i] = -1; c2i[w[idx][l]-'A'] = -1;
        }
        return false;
    }
    
    bool isSolvable(vector<string>& words, string result) {
        memset(i2c, -1, sizeof(i2c));
        memset(c2i, -1, sizeof(c2i));
        reverse(result.begin(), result.end());
        for(auto& s : words) {
            if(s.size() > result.size()) return false;
            reverse(s.begin(), s.end());
        }
        r = result; w = words;
        return solve(0, 0, 0);
    }
};

int main() {
    Solution ob;
    vector<string> v = {"SEND","MORE"};
    cout << ob.isSolvable(v, "MONEY");
    return 0;
}

อินพุต

{"SEND","MORE"}, "MONEY"

เอาต์พุต

1