乘法豎式問題(ACM)
Description
找出所有abc * de ( 三位數字乘以兩位數字 ) 的算式, 使得在完整的豎式中, 所有數字都屬於一個特定的數字集合.
輸入數字集合 ( 相鄰數字之間沒有空格 ) , 輸出所有豎式.
每個豎式前應有編號, 之後應有一個空行. 最後輸出解的總數. 具體格式見樣例輸出.
( 橫線固定爲5個 ’ - ’ , 乘號爲 ’ X ’ )
Input
輸入
一組數字集合, 數字之間沒有空格, 僅一組輸入.(數字可能有重複, 不超過20位)
如:23457777 Output
輸出
一個豎式. 每個豎式前應有編號 格式: (n爲編號)
豎式輸出完畢後有一個空行, 最後一行輸出解的個數: The number of solutions = n (n爲解的個數)
若無解則輸出The number of solutions = 0
Sample Input
2357
Sample Output
<1>
775
X 33
-----
2325
2325
-----
25575
The number of solutions = 1
思路:
嘗試所有的abc和de即可
for(abc = 111; abc <= 999; abc ++) {
for(de = 11; de <= 99; de++) {
if(abc * de滿足條件)
....
}
}
重點:
— 關於輸入:
使用sprintf輸入, sprintf是指輸出到字符串, 用法:
int abc = 111, de = 11, x = 0, y = 0, z = 0;
char buf[99];
sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z);
無需對字符串轉換, 直接將int放入了char *的數組
如果此時printf(“%s”, buf)則結果爲11111000
接下來有兩個問題:判斷和輸出
輸出:
printf("%5d\nX%4d\n-----\n%5d\b%4d\b-----\n%5d\n\n", abc, de, x, y, z);
//或者
cout << setw(5) << abc << "\nX" << setw(4) << de << "\n-----\n" << setw(5) << x << "\n" << setw(4) << y << "\n-----\n" << setw(5) << z << "\n\n";
判斷:
使用strchr(char* a, char ch)函數, 第一個參數是被匹配的數組, 第二個參數是要查找的字符, 若從數組a中找到了字符ch, 會返回第一次出現的位置的索引, 否則返回NULL
for(int i = 0; i < strlen(buf); i++) {
if(strchr(s, buf[i]) == NULL) {
flag = 0;//判斷是否在數組
break;//若有一個字符不在數組集合中, 則此豎式不滿足條件, 直接break即可
}
}
c++的sstream庫
sstream 包含了 istringstream(從 string 讀)/ostringstream(向 string
寫)/stringstream(讀寫 string)iostream 和 fstream 是兩個比較常用的IO 庫,我們這裏不再回顧,這裏簡單回顧一下 sstream。
如果你熟悉 C 語言,就知道將 int 轉換爲 string 類型其實是一件很麻煩的事情,雖然標準庫中提供了 itoa()
這種函數,但是依然需要對轉換後的 C 風格字符串(char *)通過 std::string 的構造函數構造爲 std::string。
如果使用流操作,那麼這將變得異常的簡單:
#include <string>
#include <sstream>
#include <iostrea>
int main() {
// std::stringstream 支持讀寫
std::stringstream stream;
std::string result;
int number = 12345;
stream << number; // 將 number 輸入到 stream
stream >> results; // 從 stream 讀取到 result
std::cout < result << std::endl; // 將輸出爲字符串"12345"
}
如果希望讓sstream 和 C 風格的字符串打交道,同樣也可以:
#include <sstream>
#include <iostream>
int main()
{
std::stringstream stream;
char result[6];
stream << 12345;
stream >> result;
std::cout << result << std::endl;
}
需要注意的一點就是,在進行多次IO 操作時,如果希望結果彼此不影響,需要對 stream 對象進行一次 clear() 操作:
stream.clear()
乘法豎式解決代碼:
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
int main() {
int i, flag, abc, de, x, y, z, count = 0;
char s[20], buf[99];
cin >> s;
for(int abc = 111 ; abc <= 999; abc ++) {
for(int de = 11 ; de <= 99 ; de ++) {
x = abc * (de % 10);
y = abc * (de / 10);
z = abc * de;
sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z);
flag = 1;
for(int i = 0 ; i < strlen(buf) ; i++) {
if(strchr(s, buf[i])== NULL){
flag = 0;
}
}
if(flag) {
cout << "<" << ++count << ">" << endl;
//count ++;
cout << setw(5) << abc << "\nX" << setw(4) << de << "\n-----\n" << setw(5) << x << "\n" << setw(4) << y << "\n-----\n" << setw(5) << z << "\n\n";
}
}
}
cout << "The number of solutions = " << count << endl;
}