[編程|100分] 豎式填空
時間限制:1秒
空間限制:65536K
題目描述
小Q是名小學生,他最喜歡數學中的加法豎式填空了。例如下面的填空題,每個空格表示1…9中的一個數字。
有時候這種豎式題不一定只有唯一解,小Q很想知道,給定一個這樣的豎式,總共可能的解有多少個。
被加數和加數的位數不會超過3位。和的位數不會超過4位。空格只可能存在於被加數和加數中。
輸入描述:
每個輸入數據包含多個測試點。
第一行爲測試點的個數T(T<=30)。
每個測試點包含一行,包含了三個長度大於0的字符串,分別表示被加數,加數和結果。每個字符串之間有一個空格。每個字符串只會包含“X”和“1”…“9”,其中“X”表示豎式中的空格。保證豎式至少有一個解。
輸出描述:
對於每個測試點,輸出一行,表示一共可能的解的個數。
輸入例子:
2
X7 9X 123
X X 4
輸出例子:
1
3
(樣例解釋:樣例1的解爲27+96,樣例2的解爲1+3,2+2,3+1。)
代碼(遞歸):
#include<vector>
#include<iostream>
#include<algorithm>
#include<sstream>
void dfsTwo(std::string num, int index, int remain, int& result){
if (index == num.size()){
int num_i = stoi(num);
//std::istringstream(num) >> num_i;
if (num_i == remain) result++;
return;
}
if (num[index] != 'X') dfsTwo(num, index + 1, remain, result);
else{
for (int i = 1; i < 10; ++i){
num[index] = i + '0';
dfsTwo(num, index + 1, remain, result);
}
}
}
void dfs(std::string numOne, std::string& numTwo, int index, int sum, int& result){
if (index == numOne.size()){
int num_i = stoi(numOne);
//std::istringstream(numOne) >> num_i;
dfsTwo(numTwo, 0, sum - num_i, result);
return;
}
if (numOne[index] != 'X')
dfs(numOne, numTwo, index + 1, sum, result);
else{
for (int i = 1; i < 10; ++i){
numOne[index] = i + '0';
dfs(numOne, numTwo, index + 1, sum, result);
}
}
}
int main(){
int looper = 0;
std::cin >> looper;
for (int i = 0; i < looper; ++i){
std::string numOne, numTwo;
std::cin >> numOne >> numTwo;
std::string sum;
std::cin >> sum;
int i_sum = stoi(sum);
//std::istringstream(sum) >> i_sum;
int result = 0;
dfs(numOne, numTwo, 0, i_sum, result);
std::cout << result << std::endl;
}
system("pause");
return 0;
}
代碼(迭代):
#include<vector>
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
bool isCompatible(int num, const std::string& str){
const std::string& tmp = std::to_string(num);
if (tmp.size() != str.size()) return false;
for (int i = 0; i < str.size(); ++i){
if (str[i] != 'X' && str[i] != tmp[i]){
return false;
}
}
return true;
}
int main(){
int looper = 0;
std::cin >> looper;
for (int i = 0; i < looper; ++i){
std::string numOneStr, numTwoStr, sumStr;
std::cin >> numOneStr >> numTwoStr >> sumStr;
int endOne = std::pow(10, numOneStr.size());
int startOne = endOne / 10;
int endTwo = std::pow(10, numTwoStr.size());
int startTwo = endTwo / 10;
int sum = std::stoi(sumStr);
int result = 0;
for (int i = startOne; i < endOne; ++i){
if (!isCompatible(i, numOneStr)) continue;
for (int k = startTwo; k < endTwo; ++k){
if (!isCompatible(k, numTwoStr)) continue;
result += (i + k == sum) ? 1 : 0;
}
}
std::cout << result << std::endl;
}
system("pause");
return 0;
}
總結:
1.算法渣渣,寫得不好的地方還請大大們指教;
2.最近在刷Leetcode,DP類題目,遇到問題一般都是直接先走DFS,再想想如何DP,所以做這題時,直接想到的是遞歸的解法,算法效率不高,勉強通過;
3.今天又想了一下題目,發現自己當時是太緊張了,因爲數據範圍有限,用迭代更容易;
4.算法還是太弱了,希望好好刷題,腳踏實地,不斷提升自己;