标签:20 1056 point int sum 50 ++ 15 80
// 不想思考暴力法
#include <bits/stdc++.h>
using namespace std;
int main() {
// N 非零个位 任意两个组合成二位数字
// 求所有可能组合数之和
int n, sum = 0, a[10];
cin >> n;
for(int i = 0; i < n; i++)
cin >> a[i];
// 一重循环 固定第一个元素十位
for(int i = 0; i < n; i++){
// 二重循环获取个位
for(int j = i + 1; j < n; j++)
sum += a[i] * 10 + a[j];
}
// 翻转再来一次
reverse(a, a + n);
for(int i = 0; i < n; i++){
// 二重循环获取个位
for(int j = i + 1; j < n; j++)
sum += a[i] * 10 + a[j];
}
cout << sum;
}
// 文艺简化版
#include <bits/stdc++.h>
using namespace std;
int main() {
// N 非零个位 任意两个组合成二位数字
// 求所有可能组合数之和
int n, tmp, sum = 0;
cin >> n;
for(int i = 0; i < n; i++){
cin >> tmp;
sum += tmp;
}
cout << sum * (n - 1) * 11;
}
看了看时间似乎没什么需求,况且是15分的题目,暴力一边过了。
本来还想这种组合会不会溢出,一看只有10个数并且还是两位,就没有考虑了。
学一下别人找规律。当时直接就想到的是排列组合,没想到还有人会往这个方向去想。
方法是先分类然后归纳关系,可以看到每个数字都会分别出现在个位和十位,比如 2 5 就有 25 和 52, 两个数分别做了一次个位和十位。当 2 8 , 5 8 时同理。
然后将这几个数字的全部组合列出来。
25 + 28 + 58 + 85 + 82 + 52
按照刚才的想法将个位和十位拆开分类。
20 + 5 + 20 + 8 + 50 + 8 + 80 + 5 + 80 + 2 + 50 + 2 =
20 + 20 + 50 + 50 + 80 + 80 + 2 + 2 + 5 + 5 + 8 + 8
可以看到在三个数的情况下,每个数在不同的位置上都出现了两次。用进制将他们化在一起就有。
2 * (20 + 50 + 80) + 2 * (2 + 5 + 8) =
2 * 10 * (2 + 5 + 8) + 2 * (2 + 5 + 8) =
2 * 11 * (2 + 5 + 8)
括号内是出现的数字相加,外面 11 是固定的, 2 是数字的个数减一 n - 1,这样就可以得到这题的比较简单的公式。
不过看不同位置出现次数,似乎之前哪个题目也有这样的思路。找了找是 1049 数列的片段和 这个题目。不过那个纯粹是因为暴力解不了,所以得找规律来化简一下。
至于是不是都是11这个常数可以自个多一两个数字验证一下,反正我也是剽窃来的只是随便解释一下。
标签:20,1056,point,int,sum,50,++,15,80 来源: https://www.cnblogs.com/Atl212/p/15223301.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。