蓝桥杯 连接乘积 暴力

问题描述
  192这个数很厉害,用它分别乘以1、2、3,会得到:
  192 x 1 = 192
  192 x 2 = 384
  192 x 3 = 576
  把这三个乘积连起来,得到192384576,正好是一个1~9的全排列
  我们把上面的运算定义为连接乘积:
  m x (1 ... n) = k(其中m > 0 且 n > 1,对于上例,m = 192、n = 3、k = 192384576)
  即k是把m分别乘以1到n的乘积连接起来得到的,则称k为m和n的连接乘积。
  按字典序输出所有不同的连接乘积k,满足k是1~9的全排列
输出格式
  每个k占一行
样例输出
显然,结果中应包含一行:
192384576
暴力枚举所有情况。
关键是暴力枚举的范围怎样确定,for循环里从几到几。
可以从最终答案来考虑。
要求最终的是1~9的全排列,所以一定是9位。
读题意,m至少是1。
m为1的时候,n为9才满足9位。
就是1*1,1*2,... ,1*9。然后拼接起来就是123456789满足九位。
n的范围是1~9已经确定了,然后确定m最大为多少。
这个最大值不需要是准确值,只需要包含所有的情况即可。
当m=10000时,m*1 = 10000,m*2 = 20000。拼接起来是10位,已经超过9位了。
暴力枚举的范围确定了,然后就很容易实现了。
 1 #include <bits/stdc++.h>     
 2 using namespace std;   
 3 vector<string> ans; //存储答案 
 4 string tostring(int n) { //把数字n转换为字符串 
 5     string s = "";
 6     while (n > 0) {
 7         s.push_back(n % 10 + '0');
 8         n /= 10;
 9     }
10     reverse(s.begin(), s.end()); //反转一下 
11     return s;
12 }
13 bool check(string s) { //判断s是否是1~9的全排列数
14     if (s.length() != 9) { //如果位数不是9,不是全排列
15         return false;
16     }
17     bool vis[10];
18     memset(vis, false, sizeof vis); //首先1~9全没出现过,全为false 
19     for (int i = 0; i < s.length(); i++) {
20         if (vis[s[i] - '0'] || s[i] == '0') { //如果有重复或有零,不是全排列
21             return false;
22         }
23         vis[s[i] - '0'] = true; //s[i]出现了,标记一下 
24     }
25     return true;
26 }
27 int main() {
28     for (int i = 1; i <= 10000; i++) { //暴力
29         string s = "";
30         for (int j = 1; j <= 9; j++) {
31             s += tostring(i * j); //string的连接
32             if (s.length() > 9) { //如果位数已经超过9,直接跳过
33                 continue;
34             }
35             if (check(s)) {
36                 ans.push_back(s);    
37             }            
38         }        
39     }
40     sort(ans.begin(), ans.end()); //注意要排序
41     for (int i = 0; i < ans.size(); i++) {
42         cout << ans[i] << endl;    
43     }
44     return 0;    
45 }   
posted @ 2020-04-20 16:00  kyk333  阅读(205)  评论(0)    收藏  举报