题目:称砝码——现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;每种砝码对应的数量为x1,x2,x3...xn。现在要用这些砝码去称物体的重量,问能称出多少中不同的重量。
注:重量包括0
输入描述:
输入包含多组测试数据。
对于每组测试数据:
第一行:n --- 砝码数(范围[1,10])
第二行:m1 m2 m3 ... mn --- 每个砝码的重量(范围[1,2000])
第三行:x1 x2 x3 .... xn --- 每个砝码的数量(范围[1,6])
输出描述:
利用给定的砝码可以称出的不同的重量数
输入例子:
2
1 2
2 1
输出例子:
5
解答:
事实上就是求
Sum = m[0]*x[0]+m[1]*x[1]+m[2]*x[2]+
m[3]*x[3]+m[4]*x[4]+m[5]*x[5]+
m[6]*x[6]+m[7]*x[7]+m[8]*x[8]+
m[9]*x[9]
的x[i]的值从0增长到x[i]的所有的可能的值。
我将Sum存入vector中,每次得到一个值,检查是否重复,最后输出Sum的size。
在求Sum的时候,用了三层循环:
第一层循环了x数列中所有的元素+1之后相乘的值,这是所有的可能性。比如例子中,重量1的有2个,重量2的有1个,则所有的可能性有{00}{10}{20}{01}{11}{21}一共(2+1)*(1+1)六种。
第二层拟合m[i]*x[i],其中,为了让x[i]依次变动,我将称号后面的这个值改为((x[i] - j) % (round / chuShu)),这样每个x[i]就像进位一样依次变动,遍历所有的可能性。式子中的chuShu在第三层循环。
第三层计算每个((x[i] - j) % (round / chuShu))的chuShu是多少。x[0]的chuShu对应的是x[0],x[1]对应的是x[0]*x[1],以此类推。
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 int main() { 6 bool flag = true; 7 int n, i, round = 1, littleSum = 0, chuShu = 1; 8 int m[10] = { 0 }, x[10] = { 0 }; 9 vector<int> Sum = {0}; 10 cin >> n; //得到n 11 for (auto i = 0; i < n; i++) 12 { 13 cin >> m[i]; //得到m 14 } 15 for (auto i = 0; i < n; i++) 16 { 17 cin >> x[i]; //得到x 18 round *= (x[i]+1); //计算出sum有多少种可能 19 } 20 for (auto j = 0; j != round; j++) //每种可能计算一次 21 { 22 for (auto i = 0; i != 10; i++) //每次计算都要从m[0]到m[9],不过n后面的m都是0,所以无所谓。 23 { 24 for (auto k = 0; k != i + 1; k++) 25 { 26 if (k<n) 27 { 28 chuShu *= x[k]; //除数(其实应该是求余数)对应i的值进行累乘。 29 } 30 } 31 littleSum += m[i] * ((x[i] - j) % (round / chuShu)); //计算该种可能性的一部分 32 chuShu = 1; //除数置1 33 } 34 for (auto x: Sum) 35 { 36 if (x == littleSum) //判断Sum中是否以及存在得到的可能性。 37 { 38 flag = false; 39 break; 40 } 41 } 42 if (flag) 43 { 44 Sum.push_back(littleSum); 45 } 46 flag = true; 47 littleSum = 0; 48 chuShu = 1; 49 } 50 cout << Sum.size(); 51 }
感觉自己做的太麻烦,肯定有更快的算法,我去找找有没有大神分享出来。