- 資料結構與演算法
- 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
廣告