货物摆放 蓝桥杯
·
目录
前言
众所周知,蓝桥杯还是挺适合暴力的
但,如果遇到十几位以上的数,在套上3个for循环,那就呵呵了;
所以,今天就介绍一下缩短运行时间的方法。
方法一 (货物摆放详解)
如果非要用3重循环,
那该怎么优化呢??

优化前 又臭又长
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
unsigned long long i,j,k,t,h,cnt=0,N=2021041820210418,k, ;
for(i=1;i<=N;i++){
for(j=1;j*i<=N;j++){
k=N%(i*j);
h=N/i/j;
if(k)continue;
else {
for(t=1;t<=cnt;t++)if(i==a[t]&&j==b[t]&&c[t]==h)break;
if(t>cnt){cnt++;a[cnt]=i;b[cnt]=j;c[cnt]=h;}
}
}
}
cout<<cnt;
return 0;
}
16位的大数字,还是三重循环,真是要命了!!
优化后
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
unsigned long long N=2021041820210418;
long long i,j,k,sum=0;
for(i=1;i*i*i<=N;i++) //注意每个for循环的终止条件!!
if(N%i==0)
for(j=i;i*j*j<=N;j++) //j=i+1就不对了,必须是j=i
if(N/i%j==0){
k=N/i/j;
if(i==j||i==k||j==k)sum+=3;
else if(i==j&&i==k)sum++;//3个相同
else sum+=6;}
cout<<sum;
return 0;
}
解开本题的关键,就是找N的因子 i j k
满足i*j*k=N
优化点
1.先求出满足条件3个因子的组合,并按从小到大的顺序
这样不仅缩小2个for循环的范围,还有利于后面的排序
2.对组合数排序,求出一种组合数有几种排序方法
三个数都相同 就是1种,
两个数相同 有3种,
各不同 是6种
而且,求排序数 就不用再查重,不用再笨拙的加for循环
3.其他
判断3个相同时,
else if(i==j&&i==k)sum++; 两两相同就可以, 没必要(i==j&&i==k&&j==k)
总之,先找组合,再排序
方法二
可以用数组来标记重复的元素
先把数组初始化为0,
出现,就赋值为1
举个栗子
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s[90000];
int ex[27];
int i,j,k,sum=0,cnt=0;
cin>>s;
int len=strlen(s);
for(i=0;i<=len-1;i++){
memset(ex,0,sizeof(int)*27);//全部初始化为0
cnt=0;
for(j=i;j<=len-1;j++){
if(!ex[s[j]-'a']){cnt++;
ex[s[j]-'a']=100;}//出现就=100
else if(ex[s[j]-'a']>0){cnt--; ex[s[j]-'a']=-50; }
// else if(ex[s[j]-'a']<0)
sum+=cnt;
}
}
cout<<sum;
return 0;
}
当然,也有局限性,适用于单一元素的查重
方法三
填空题 要是真优化不了,就放着,让它慢慢算吧,
反正提交的结果对就行,
用时间白嫖点分数
也挺好的
更多推荐
所有评论(0)