- 数据结构与算法
- DSA - 首页
- DSA - 概述
- DSA - 环境设置
- DSA - 算法基础
- DSA - 渐进分析
- 数据结构
- DSA - 数据结构基础
- DSA - 数据结构和类型
- DSA - 数组数据结构
- 链表
- DSA - 链表数据结构
- DSA - 双向链表数据结构
- DSA - 循环链表数据结构
- 栈与队列
- DSA - 栈数据结构
- DSA - 表达式解析
- DSA - 队列数据结构
- 搜索算法
- DSA - 搜索算法
- DSA - 线性搜索算法
- DSA - 二分搜索算法
- DSA - 插值搜索
- DSA - 跳跃搜索算法
- DSA - 指数搜索
- DSA - 斐波那契搜索
- DSA - 子列表搜索
- DSA - 哈希表
- 排序算法
- DSA - 排序算法
- DSA - 冒泡排序算法
- DSA - 插入排序算法
- DSA - 选择排序算法
- DSA - 归并排序算法
- DSA - 希尔排序算法
- DSA - 堆排序
- DSA - 桶排序算法
- DSA - 计数排序算法
- DSA - 基数排序算法
- DSA - 快速排序算法
- 图数据结构
- DSA - 图数据结构
- DSA - 深度优先遍历
- DSA - 广度优先遍历
- DSA - 生成树
- 树数据结构
- DSA - 树数据结构
- DSA - 树的遍历
- DSA - 二叉搜索树
- DSA - AVL树
- DSA - 红黑树
- DSA - B树
- DSA - B+树
- DSA - 伸展树
- DSA - 字典树
- DSA - 堆数据结构
- 递归
- DSA - 递归算法
- DSA - 使用递归实现汉诺塔
- DSA - 使用递归实现斐波那契数列
- 分治法
- DSA - 分治法
- DSA - 最大最小值问题
- DSA - Strassen矩阵乘法
- DSA - Karatsuba算法
- 贪心算法
- DSA - 贪心算法
- DSA - 旅行商问题(贪心法)
- DSA - Prim最小生成树
- DSA - Kruskal最小生成树
- DSA - Dijkstra最短路径算法
- DSA - 地图着色算法
- DSA - 分数背包问题
- DSA - 带截止期限的作业排序
- DSA - 最优合并模式算法
- 动态规划
- DSA - 动态规划
- DSA - 矩阵链乘法
- DSA - Floyd-Warshall算法
- DSA - 0-1背包问题
- DSA - 最长公共子序列算法
- DSA - 旅行商问题(动态规划法)
- 近似算法
- DSA - 近似算法
- DSA - 顶点覆盖算法
- DSA - 集合覆盖问题
- DSA - 旅行商问题(近似算法)
- 随机化算法
- DSA - 随机化算法
- DSA - 随机化快速排序算法
- DSA - Karger最小割算法
- DSA - Fisher-Yates洗牌算法
- DSA有用资源
- DSA - 问答
- DSA - 快速指南
- DSA - 有用资源
- DSA - 讨论
求解数独谜题
什么是算术字谜?
算术字谜,也称为密码,是一种数学谜题,我们将数字分配给字母或符号。最终目标是找到每个字母的唯一数字分配,以便给定的数学运算成立。在这个谜题中,执行加法运算的等式是最常用的。但是,它也涉及其他算术运算,例如减法、乘法等。
算术字谜的规则如下:
我们只能使用 0 到 9 的数字来表示谜题中唯一的字母。
在整个等式中,不能将相同的数字分配给不同的字母。
用数字替换字母后形成的等式在数学上应该是正确的。
输入输出场景
假设给定的等式是:
Input: B A S E B A L L ---------- G A M E S
在上式中,单词“BASE”和“BALL”相加得到“GAMES”。算法将把给定单词的每个字母与 0 到 9 的唯一数字相关联。对于上述输入,输出应为:
使用回溯法求解算术字谜
求解算术字谜的朴素方法是从左边的每个操作数中取一个字母,然后一个接一个地分配数字 0 到 9。分配数字后,检查算术表达式的有效性。但是,这种方法对于较大的操作数效率低下。
要使用回溯法求解算术字谜,请按照以下步骤操作:
首先,识别给定算术表达式中的所有唯一字符。
接下来,尝试将数字分配给字母。如果发现重复,则回溯并取消分配。这样将生成每个字母的所有可能的数字组合。
现在,用数字替换字母,并检查表达式是否正确。
示例
在下面的示例中,我们将实际演示如何求解算术字谜。
#include <stdio.h> #include <string.h> //set 1, when one character is assigned previously int use[10] = {0}; // structure struct node { char letter; int value; }; int isValid(struct node* nodeList, const int count, char* s1, char* s2, char* s3) { int val1 = 0, val2 = 0, val3 = 0, m = 1, j, i; //find number for first string for (i = strlen(s1) - 1; i >= 0; i--) { char ch = s1[i]; for (j = 0; j < count; j++) //when ch is present, break the loop if (nodeList[j].letter == ch) break; val1 += m * nodeList[j].value; m *= 10; } m = 1; //find number for second string for (i = strlen(s2) - 1; i >= 0; i--) { char ch = s2[i]; for (j = 0; j < count; j++) if (nodeList[j].letter == ch) break; val2 += m * nodeList[j].value; m *= 10; } m = 1; //find number for third string for (i = strlen(s3) - 1; i >= 0; i--) { char ch = s3[i]; for (j = 0; j < count; j++) if (nodeList[j].letter == ch) break; val3 += m * nodeList[j].value; m *= 10; } //check whether the sum is same as 3rd string or not if (val3 == (val1 + val2)) return 1; return 0; } int permutation(int count, struct node* nodeList, int n, char* s1, char* s2, char* s3) { //when values are assigned for all characters if (n == count - 1) { for (int i = 0; i < 10; i++) { // for those numbers, which are not used if (use[i] == 0) { //assign value i nodeList[n].value = i; //check validation if (isValid(nodeList, count, s1, s2, s3) == 1) { printf("Solution found: "); //print code, which are assigned for (int j = 0; j < count; j++) printf(" %c = %d", nodeList[j].letter, nodeList[j].value); return 1; } } } return 0; } for (int i = 0; i < 10; i++) { // for those numbers, which are not used if (use[i] == 0) { //assign value i and mark as not available for future use nodeList[n].value = i; use[i] = 1; //go for next characters if (permutation(count, nodeList, n + 1, s1, s2, s3) == 1) return 1; //when backtracks, make available again use[i] = 0; } } return 0; } int solvePuzzle(char* s1, char* s2, char* s3) { //Number of unique characters int uniqueChar = 0; int len1 = strlen(s1); int len2 = strlen(s2); int len3 = strlen(s3); //There are 26 different characters int freq[26] = {0}; for (int i = 0; i < len1; i++) ++freq[s1[i] - 'A']; for (int i = 0; i < len2; i++) ++freq[s2[i] - 'A']; for (int i = 0; i < len3; i++) ++freq[s3[i] - 'A']; for (int i = 0; i < 26; i++) //whose frequency is > 0, they are present if (freq[i] > 0) uniqueChar++; //as there are 10 digits in decimal system if (uniqueChar > 10) { printf("Invalid strings"); return 0; } struct node nodeList[uniqueChar]; //assign all characters found in three strings for (int i = 0, j = 0; i < 26; i++) { if (freq[i] > 0) { nodeList[j].letter = (char)(i + 'A'); j++; } } return permutation(uniqueChar, nodeList, 0, s1, s2, s3); } int main() { char s1[] = "BASE"; char s2[] = "BALL"; char s3[] = "GAMES"; if (solvePuzzle(s1, s2, s3) == 0) printf("No solution"); return 0; }
#include <iostream> #include <vector> using namespace std; //set 1, when one character is assigned previously vector<int> use(10); struct node { char letter; int value; }; int isValid(node* nodeList, const int count, string s1, string s2, string s3) { int val1 = 0, val2 = 0, val3 = 0, m = 1, j, i; //find number for first string for (i = s1.length() - 1; i >= 0; i--) { char ch = s1[i]; for (j = 0; j < count; j++) //when ch is present, break the loop if (nodeList[j].letter == ch) break; val1 += m * nodeList[j].value; m *= 10; } m = 1; //find number for second string for (i = s2.length() - 1; i >= 0; i--) { char ch = s2[i]; for (j = 0; j < count; j++) if (nodeList[j].letter == ch) break; val2 += m * nodeList[j].value; m *= 10; } m = 1; //find number for third string for (i = s3.length() - 1; i >= 0; i--) { char ch = s3[i]; for (j = 0; j < count; j++) if (nodeList[j].letter == ch) break; val3 += m * nodeList[j].value; m *= 10; } //check whether the sum is same as 3rd string or not if (val3 == (val1 + val2)) return 1; return 0; } bool permutation(int count, node* nodeList, int n, string s1, string s2, string s3) { //when values are assigned for all characters if (n == count - 1) { for (int i = 0; i < 10; i++) { // for those numbers, which are not used if (use[i] == 0) { //assign value i nodeList[n].value = i; //check validation if (isValid(nodeList, count, s1, s2, s3) == 1) { cout << "Solution found: "; //print code, which are assigned for (int j = 0; j < count; j++) cout << " " << nodeList[j].letter << " = " << nodeList[j].value; return true; } } } return false; } for (int i = 0; i < 10; i++) { // for those numbers, which are not used if (use[i] == 0) { //assign value i and mark as not available for future use nodeList[n].value = i; use[i] = 1; //go for next characters if (permutation(count, nodeList, n + 1, s1, s2, s3)) return true; //when backtracks, make available again use[i] = 0; } } return false; } bool solvePuzzle(string s1, string s2,string s3) { //Number of unique characters int uniqueChar = 0; int len1 = s1.length(); int len2 = s2.length(); int len3 = s3.length(); //There are 26 different characters vector<int> freq(26); for (int i = 0; i < len1; i++) ++freq[s1[i] - 'A']; for (int i = 0; i < len2; i++) ++freq[s2[i] - 'A']; for (int i = 0; i < len3; i++) ++freq[s3[i] - 'A']; for (int i = 0; i < 26; i++) //whose frequency is > 0, they are present if (freq[i] > 0) uniqueChar++; //as there are 10 digits in decimal system if (uniqueChar > 10) { cout << "Invalid strings"; return 0; } node nodeList[uniqueChar]; //assign all characters found in three strings for (int i = 0, j = 0; i < 26; i++) { if (freq[i] > 0) { nodeList[j].letter = char(i + 'A'); j++; } } return permutation(uniqueChar, nodeList, 0, s1, s2, s3); } int main() { string s1 = "BASE"; string s2 = "BALL"; string s3 = "GAMES"; if (solvePuzzle(s1, s2, s3) == false) cout << "No solution"; }
public class Main { // Set 1 when one character is assigned previously int[] use = new int[10]; class Node { char letter; int value; } public int isValid(Node[] nodeList, int count, String s1, String s2, String s3) { int val1 = 0, val2 = 0, val3 = 0; int m = 1; int j, i; //find number for first string for (i = s1.length() - 1; i >= 0; i--) { char ch = s1.charAt(i); for (j = 0; j < count; j++) { // when ch is present, break the loop if (nodeList[j].letter == ch) { break; } } val1 += m * nodeList[j].value; m *= 10; } m = 1; //find number for second string for (i = s2.length() - 1; i >= 0; i--) { char ch = s2.charAt(i); for (j = 0; j < count; j++) { if (nodeList[j].letter == ch) { break; } } val2 += m * nodeList[j].value; m *= 10; } m = 1; //find number for third string for (i = s3.length() - 1; i >= 0; i--) { char ch = s3.charAt(i); for (j = 0; j < count; j++) { if (nodeList[j].letter == ch) { break; } } val3 += m * nodeList[j].value; m *= 10; } //check whether the sum is same as 3rd string or not if (val3 == (val1 + val2)) { return 1; } return 0; } public int permutation(int count, Node[] nodeList, int n, String s1, String s2, String s3) { //when values are assign if (n == count - 1) { // for those numbers, which are not used for (int i = 0; i < 10; i++) { if (use[i] == 0) { //assign value i nodeList[n].value = i; if (isValid(nodeList, count, s1, s2, s3) == 1) { System.out.print("Solution found:"); //print code, which are assigned for (int j = 0; j < count; j++) { System.out.print(" " + nodeList[j].letter + " = " + nodeList[j].value); } return 1; } } } return 0; } // for those numbers, which are not used for (int i = 0; i < 10; i++) { if (use[i] == 0) { //assign value i and mark as not available for future use nodeList[n].value = i; use[i] = 1; if (permutation(count, nodeList, n + 1, s1, s2, s3) == 1) { //go for next characters return 1; } //when backtracks, make available again use[i] = 0; } } return 0; } public int solvePuzzle(String s1, String s2, String s3) { //Number of unique characters int uniqueChar = 0; int len1 = s1.length(); int len2 = s2.length(); int len3 = s3.length(); // There are 26 different characters int[] freq = new int[26]; for (int i = 0; i < len1; i++) { freq[s1.charAt(i) - 'A']++; } for (int i = 0; i < len2; i++) { freq[s2.charAt(i) - 'A']++; } for (int i = 0; i < len3; i++) { freq[s3.charAt(i) - 'A']++; } //whose frequency is > 0, they are present for (int i = 0; i < 26; i++) { if (freq[i] > 0) { uniqueChar++; } } //as there are 10 digits in decimal system if (uniqueChar > 10) { System.out.println("Invalid strings"); return 0; } Node[] nodeList = new Node[uniqueChar]; int j = 0; for (int i = 0; i < 26; i++) { //assign all characters found in three strings if (freq[i] > 0) { nodeList[j] = new Node(); nodeList[j].letter = (char) (i + 'A'); j++; } } return permutation(uniqueChar, nodeList, 0, s1, s2, s3); } public static void main(String[] args) { Main main = new Main(); String s1 = "BASE"; String s2 = "BALL"; String s3 = "GAMES"; if (main.solvePuzzle(s1, s2, s3) == 0) { System.out.println("No solution"); } } }
class Main: #Set 1 when one character is assigned previously use = [0] * 10 class Node: def __init__(self): self.letter = '' self.value = 0 def isValid(self, nodeList, count, s1, s2, s3): val1 = 0 val2 = 0 val3 = 0 m = 1 j = 0 i = 0 #find number for first string for i in range(len(s1) - 1, -1, -1): ch = s1[i] for j in range(count): #when ch is present, break the loop if nodeList[j].letter == ch: break val1 += m * nodeList[j].value m *= 10 m = 1 #find number for the second string for i in range(len(s2) - 1, -1, -1): ch = s2[i] for j in range(count): if nodeList[j].letter == ch: break val2 += m * nodeList[j].value m *= 10 m = 1 #find number for the third string for i in range(len(s3) - 1, -1, -1): ch = s3[i] for j in range(count): if nodeList[j].letter == ch: break val3 += m * nodeList[j].value m *= 10 #check whether the sum is the same as the 3rd string or not if val3 == (val1 + val2): return 1 return 0 def permutation(self, count, nodeList, n, s1, s2, s3): #when values are assigned if n == count - 1: for i in range(10): #for those numbers, which are not used if self.use[i] == 0: #assign value i nodeList[n].value = i if self.isValid(nodeList, count, s1, s2, s3) == 1: print("Solution found:", end='') #print code, which is assigned for j in range(count): print(f" {nodeList[j].letter} = {nodeList[j].value}", end='') return 1 return 0 for i in range(10): #for those numbers, which are not used if self.use[i] == 0: #assign value i and mark as not available for future use nodeList[n].value = i self.use[i] = 1 if self.permutation(count, nodeList, n + 1, s1, s2, s3) == 1: #go for the next characters return 1 #when backtracking, make available again self.use[i] = 0 return 0 def solvePuzzle(self, s1, s2, s3): #Number of unique characters uniqueChar = 0 len1 = len(s1) len2 = len(s2) len3 = len(s3) #There are 26 different characters freq = [0] * 26 for i in range(len1): freq[ord(s1[i]) - ord('A')] += 1 for i in range(len2): freq[ord(s2[i]) - ord('A')] += 1 for i in range(len3): freq[ord(s3[i]) - ord('A')] += 1 for i in range(26): #whose frequency is > 0, they are present if freq[i] > 0: uniqueChar += 1 #as there are 10 digits in the decimal system if uniqueChar > 10: print("Invalid strings") return 0 nodeList = [self.Node() for _ in range(uniqueChar)] j = 0 for i in range(26): #assign all characters found in three strings if freq[i] > 0: nodeList[j].letter = chr(i + ord('A')) j += 1 return self.permutation(uniqueChar, nodeList, 0, s1, s2, s3) if __name__ == "__main__": main = Main() s1 = "BASE" s2 = "BALL" s3 = "GAMES" if main.solvePuzzle(s1, s2, s3) == 0: print("No solution")
输出
Solution found: A = 4 B = 2 E = 1 G = 0 L = 5 M = 9 S = 6
广告