問題描述:找出所有形如abcde(三位數(shù)乘以兩位數(shù))的算式,使得在完成的豎式中,所有數(shù)字都屬于一個特定的數(shù)字集合。輸入數(shù)字集合(相鄰數(shù)字之間沒有空格),輸出所有豎式。每個豎式前應(yīng)有編號,之后應(yīng)有一個空行。最后輸出解的總數(shù)。具體格式見樣例輸出(為了便于觀察,豎式中的空格改用小數(shù)點(diǎn)顯示,但所寫程序中應(yīng)該輸出空格,而非小數(shù)點(diǎn))
思路:這道題因?yàn)橄薅╝bcde的格式,所以100<=abc<=999,10<=de<=99(不過書上的下限是111和11,也不知為啥,可能我題意理解有些許偏差),只需要遍歷所有的可能性就可以了。
關(guān)鍵點(diǎn)一:如何遍歷de的個位十位與abc的相乘。
關(guān)鍵點(diǎn)二:如何判斷相乘的結(jié)果在不在輸入的數(shù)字集合中。
關(guān)鍵點(diǎn)三:如何輸出合適的空格。
由于題目并不復(fù)雜,所以使用我并不熟練的C++做。
為了解決關(guān)鍵點(diǎn)二,我將判斷這個東西的包裝成了一個函數(shù),具體代碼如下,思路在注釋中(好像又做得很復(fù)雜)。
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
int func(int num,string num_char,int flag)
{
char numChar;
int idx;
while (num)//判斷abc是不是滿足要求
{
numChar = '0' + num % 10;//
idx = num_char.find(numChar);
if (idx == string::npos) {
flag = 0;//如果有一個不在序列之中,就標(biāo)志其不合法,然后跳出兩重循環(huán),執(zhí)行下一個數(shù)
return flag;
}
else
{
num = num / 10;
continue;
}
}
return flag;
}
int main()
{
int num, i,j,flag,number;
string num_char;
string res;
stringstream ss;
while (cin>>num_char)
{
number = 0;
for (i = 111; i <= 999; i++)
{
for (j = 11; j <= 99; j++)
{
flag = 1;
num = i;
flag=func(num, num_char, flag);//判斷abc是否合法
num = j;
flag = func(num, num_char, flag);//判斷de是否合法
num = i * (j%10);
flag = func(num, num_char, flag);
num = i * (j/10);
flag = func(num, num_char, flag);
num = i*j;
flag = func(num, num_char, flag);//判斷i*j是否合法
if (flag)
{
cout << '<' << ++number << '>' << endl;
cout <<" "<<i<< endl;
cout <<"X "<<j<< endl;
cout <<"-----"<< endl;
cout <<setw(5)<< i * (j % 10) << endl;
cout << setw(4) << i * (j / 10) << endl;
cout << "-----" << endl;
cout << i*j<< endl;
}
}
}
cout <<"The number of solutions="<<number<< endl;
}
}
對比一下標(biāo)準(zhǔn)答案的代碼,體會標(biāo)準(zhǔn)答案的高明之處:
#include<stdio.h>
#include<string.h>
int main()
{
int count = 0;
char s[20], buf[99];
scanf("%s", s);
for (int abc = 111; abc <= 999; abc++)
{
for (int de = 11; de <= 99;de++)
{
int x = abc * (de % 10), y = abc * (de / 10), z = abc * de;
sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z);
int ok = 1;
for (int i=0; i < strlen(buf); i++)
{
if (strchr(s, buf[i]) == NULL) ok = 0;
}
if(ok)
{
printf("<%d>\n", ++count);
printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z);
}
}
}
printf("The number of solutions=%d\n", count);
}
不同之處:
1.標(biāo)準(zhǔn)答案使用了sprintf,可以將所有的數(shù)字都作為一個字符串打印到數(shù)組中,極大簡便了判斷,使代碼更加簡潔。而且執(zhí)行效率更高,受其啟發(fā),修改了代碼
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
int func(string num_char,string res,int flag)
{
int idx;
for (int i = 0; i < res.length(); i++)
{
idx = num_char.find(res[i]);
if (idx == string::npos) {
flag = 0;//如果有一個不在序列之中,就標(biāo)志其不合法,然后跳出兩重循環(huán),執(zhí)行下一個數(shù)
return flag;
}
else continue;
}
return flag;
}
int main()
{
int i,j,flag,number;
string num_char;
string res;
stringstream ss;
while (cin>>num_char)
{
number = 0;
for (i = 111; i <= 999; i++)
{
for (j = 11; j <= 99; j++)
{
flag = 1;
ss << i<<j<< i * (j % 10) << i * (j / 10) << i * j;
ss >> res;
flag = func( num_char,res, flag);//判斷i*j是否合法
res.clear();
ss.clear();
if (flag)
{
cout << '<' << ++number << '>' <<endl<< " " << i << endl << "X " << j << endl << "-----" << endl << setw(5) << i * (j % 10) << endl << setw(4) << i * (j / 10) << endl << "-----" << endl << i * j << endl;
}
}
}
cout <<"The number of solutions="<<number<< endl;
}
}

由于本周時間多投資在了另外一邊,刷題時間不是很充裕。閑下來后盡量多補(bǔ)點(diǎn)題。