暴力
其实暴力迭代解题也是有技巧的,并不是无脑的,下面总结了几个个人感觉比较有技巧的暴力题。
2018乘积尾零
如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?
5650 4542 3554 473 946 4114 3871 9073 90 4329
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899
1486 5722 3135 1170 4014 5510 5120 729 2880 9019
2049 698 4582 4346 4427 646 9742 7340 1230 7683
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649
6701 6645 1671 5978 2704 9926 295 3125 3878 6785
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074
689 5510 8243 6114 337 4096 8199 7313 3685 211
注意:需要提交的是一个整数,表示末尾零的个数。不要填写任何多余内容。
将所有数相乘,爆long long 的问题,直接每次保留后四位非零的数字即可
#include<iostream>
#include<string>
using namespace std;
//保留后四位
int main() {
long long t,p,e = 0,temp;
cin >> temp;
for (int i = 0;i<99;i++) {
cin >> t;
p = t * temp;
while (p % 10 == 0) {
//保留后四位非零数字
e++; p /= 10;
}
temp = p%10000;
}
cout<<e;
return 0;
}
2017等差素数列
标题:等差素数列
2,3,5,7,11,13,….是素数序列。
类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。
上边的数列公差为30,长度为6。
2004年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。
这是数论领域一项惊人的成果!
有这一理论为基础,请你借助手中的计算机,满怀信心地搜索:
长度为10的等差素数列,其公差最小值是多少?
注意:需要提交的是一个整数,不要填写任何多余的内容和说明文字。
暴力枚举,设置一个标记数组,标记1-100000的素数,两层循环遍历所有公差和起始位置即可。
#include <iostream>
using namespace std;
int a[1000000];
int f(int x)
{
for(int i = 2; i < x; i++) {
if(x%i == 0) {
return 0;
}
}
return 1;
}
int main()
{
for(int i = 2; i < 100000; i++) {
if( f(i) ) {
a[i] = 1; //说明i为素数 赋1
}
}
for(int cha = 1; cha < 10000; cha++) {
//公差
for(int i = 2; i < 100000; i++ ) {
//起始位置
int count;
for(count= 0 ; count < 10; count++) {
if(a[ i+count*cha ] != 1) {
//说明这个数不是素数
break;
}
}
if(count == 10) {
cout << cha;
return 0;
}
}
}
return 0;
} //210
2015加法变乘法
我们都知道:1+2+3+ … + 49 = 1225
现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如:
1+2+3+…+1011+12+…+2728+29+…+49 = 2015
就是符合要求的答案。
请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。
注意:需要你提交的是一个整数,不要填写任何多余的内容。
首先二层循环遍历枚举所有的变乘法的加法位置,第三层循环按照标记的变乘法的位置验证即可:
#include<iostream>
using namespace std;
int main() {
int i,j,k,res = 0;
for (i = 1;i<=48;i++) {
for (j = i+2;j<=48;j++) {
for (k = 1;k<=49;k++) {
if (k==i||k==j) {
res+=k*(k+1);
k++;
}
else {
res+=k;
}
}
if (res==2015) cout<<i<<endl;
res = 0;
}
}
return 0;
}
2019等差数列:
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。 现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有 几项?
【输入格式】
输入的第一行包含一个整数 N。 第二行包含 N 个整数 A1,A2,··· ,AN。(注意 A1 ∼ AN 并不一定是按等差数 列中的顺序给出)
【输出格式】
输出一个整数表示答案。
【样例输入】
5
2 6 4 10 20
【样例输出】
10
【样例说明】
包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。
输入之后排序去重,排序之后按照数组中依次进行每一项的差值求最大公约数(使其数列最短),那么最短数列即为最后最大值减去最小值除以最大公约数(即最大公差)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int gcd(int a,int b) {
if (a%b==0) return b;
return gcd(b,a%b);
}
int main() {
int n,g,mn = 0x3f3f3f3f,mx = -0x3f3f3f3f;
cin>>n;
vector<int> a(n);
for (int i = 0;i<n;i++) {
cin>>a[i];
}
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());//排序去重
for (int i = 2;i<n;i++) {
if (i==2) g = gcd(a[2]-a[1],a[1]-a[0]);
g = gcd(a[i]-a[i-1],g);
}
cout<<(a[n-1]-a[0])/g+1;
return 0;
}
2019数的分解
问题描述:
把2019分解成3个各不相同的正整数之和,并且要求每个正整数都不包含数字2和4,一共有多少种不同的分解方法?
注意交换3个整数的顺序被视为同一种方法,例如1000+1001+18和1001+1000+18被视为同一种。
样例输出:
40785
三层循环依次遍历互不相同的三个数最后验证即可。
#include<iostream>
using namespace std;
int check(int i, int j, int k) {
while (i) {
if (i % 10 == 2 || i % 10 == 4) return 0;
i /= 10;
}
while (j) {
if (j % 10 == 2 || j % 10 == 4) return 0;
j /= 10;
}
while (k) {
if (k % 10 == 2 || k % 10 == 4) return 0;
k /= 10;
}
return 1;
}
int main() {
int cnt = 0,temp = 0,leap = 0;
for (int i = 1;i<=2018;i++) {
for (int j = i+1;j<2018;j++) {
for (int k = j+