乘法豎式問題(ACM)

乘法豎式問題(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章