在做这个题的时候感受到了算法的魅力
之前用最容易想到的暴力求素数的方法 求10000000以内的素数要用40多秒以上。。
改成筛选法后一下降到2秒多
主要参考了这个大牛的博客
先看一下题目吧
我用的方法需要求出10000000以内的所有素数 然后用这个素数数组去求某一个数质因数的数目
但是之前没考虑到效率问题 光是求10000000以内的素数就花了40多秒 超时太严重了 提交到oj明显超时了 后来改了一下 本地运行2秒多
提交才通过了 整个过程 640ms 当然oj的配置比我的电脑好很多倍
#include <iostream>
#include <vector>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 10000000;
bool a[MAX];
//bool isPrime(int n)
//{
// bool flag = true;
// for(int i = 2; i * i <= n; ++i)
// {
//
// if(n % i == 0)
// {
// flag = false;
// break;
// }
// }
// return flag;
//}
class Node1//最大者优先
{
public:
int m;
int n;
bool operator < (const Node1 &a)const
{
bool flag;
if(n < a.n)flag = true;
else if(n == a.n)
{
if(m < a.m)flag = true;
else flag = false;
}
else
{
flag = false;
}
return flag;
}
};
class Node2//最小者优先
{
public:
int m;
int n;
bool operator < (const Node2 &a)const
{
bool flag;
if(n < a.n)flag = false;
else if(n == a.n)
{
if(m < a.m)flag = false;
else flag = true;
}
else
{
flag = true;
}
return flag;
}
};
int main()
{
vector<int> v;
// freopen("in2.txt","r",stdin);
// freopen("my_out.txt","w",stdout);
for(int i = 2; i < MAX; ++i)
{
if(!a[i])
{
v.push_back(i);
for(int j = i; j < MAX; j += i)
a[j] = true;
}
}
// vector<int>::iterator i;
// for(i = v.begin(); i != v.end(); ++i)
// cout<<*i<<",";
// cout<<endl<<v.size()<<endl;
// for(int j = 2; j < MAX; j++)
// cout<<a[j]<<" ";
// cout<<endl;
priority_queue<Node1> q1;
priority_queue<Node2> q2;
int num;
scanf("%d",&num);
while(num--)
{
for(int i = 0; i < 10; ++i)
{
int tem,total = 0;
scanf("%d",&tem);
if(find(v.begin(),v.end(),tem) != v.end())total = 0;
else
{
vector<int>::iterator m;
for(m = v.begin(); m !=v.end(); ++m)
{
if(*m > tem)break;
}
vector<int>::iterator n;
for(n = v.begin(); n != m; ++n)
{
if(tem % *n == 0)total++;
}
}
Node1 tem1;
Node2 tem2;
tem1.m = tem,tem1.n = total;
tem2.m = tem,tem2.n = total;
// cout<<"tem1 = "<<tem1.m<<" "<<tem1.n<<endl;
// cout<<"tem2 = "<<tem2.m<<" "<<tem2.n<<endl;
q1.push(tem1);
q2.push(tem2);
}
printf("%d %d\n",q1.top().m,q2.top().m);
// cout<<q1.top().n<<" "<<q2.top().n<<endl;
q1.pop();
q2.pop();
}
return 0;
}
看到网上其他人做的求解质因数的方法 。。。
原理是从开始除 能整除的话就是质因数 然后循环去掉这个质因数 就可以求出来了 不用素数表
#include <iostream>
using namespace std;
int Facter(int n)
{
int n_tem, sum = 0;
n_tem = n;
for(int i = 2;i <= n;++i)
{
if(n % i == 0 && n_tem != i)
{
sum++;
cout<<i<<" ";
while(n % i == 0)
n = n / i;
}
}
cout<<endl;
return sum;
}
int main()
{
int k;
while(cin>>k)
cout<<Facter(k)<<endl;
return 0;
}
按照上面的方法在做了一次这题 时间空间都下降了很多
256kB | 280ms | 1179 B |
14204kB | 640ms | 2807 B |
没有用优级队列了 直接用队列做的。。
#include <iostream>
#include <deque>
#include <algorithm>
#include <cstdio>
using namespace std;
int Facter(int n)
{
int n_tem, sum = 0;
n_tem = n;
for(int i = 2; i <= n; ++i)
{
if(n % i == 0 && n_tem != i)
{
sum++;
//cout<<i<<" ";
while(n % i == 0)
n = n / i;
}
}
//cout<<endl;
return sum;
}
class Node
{
public:
int m;
int n;
bool operator < (const Node & a)const
{
bool flag;
if(n < a.n)flag = true;
else if(n == a.n)
{
if(m < a.m)flag = true;
else flag = false;
}
else flag = false;
return flag;
}
};
int main()
{
int num;
deque<Node> q;
scanf("%d",&num);
while(num--)
{
for(int i = 0; i < 10; ++i)
{
int tem;
Node q_tem;
scanf("%d",&tem);
q_tem.m = tem;
q_tem.n = Facter(tem);
q.push_back(q_tem);
}
sort(q.begin(),q.end());
printf("%d %d\n",q.back().m,q.front().m);
q.pop_back();
q.pop_front();
}
return 0;
}