A Research Problem UVA

来源:互联网 发布:云计算是什么意思啊 编辑:程序博客网 时间:2024/06/05 18:14

注意可以将欧拉函数的连乘的形式展开,从而可以去掉分母,然后就会发现欧拉函数的结果可以写成多个p^k*(p-1)连乘的形式,其中p是素数,注意k可能为0,那么我们就首先利用打表法求出所有的素数,然后对于输入的n找出n可以整除的(p-1),保存p,然后就利用dfs暴力搜索就行了,搜索的过程中要对p的个数进行计数,最后对于处理n的剩下的数m,要保证m+1也为素数并且在之前的判断中没有访问过即可,具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;typedef long long LL;LL n;vector<int> prime;const int maxn = 10000;int vis[maxn + 5];vector<int> prime2;int amount;LL ans;void Init(){int up = floor(sqrt(maxn) + 0.5);memset(vis, 0, sizeof(vis));for (int i = 2; i <= up; i++){if (!vis[i]){for (int j = i*i; j <= maxn; j += i){vis[j] = 1;}}}for (int i = 2; i <= maxn; i++){if (!vis[i]) prime.push_back(i);}}LL judge(int cur){if (cur == 1) return 1;cur++;for (int i = 0; i < prime.size() && prime[i] * prime[i] <= cur; i++){if (cur%prime[i] == 0) return -1;//此时cur不为素数}for (int i = 0; i < amount; i++){if (vis[prime2[i]] && cur == prime2[i]) return -1;}return cur;}void dfs(LL aim,int cur,int total){if (total == amount){LL res = judge(cur);if (res == -1) return;ans = min(ans,aim*res);return;}dfs(aim,cur,total+1);if (cur % (prime2[total] - 1) == 0){vis[prime2[total]] = 1;cur = cur / (prime2[total] - 1);aim *= prime2[total];while (true){dfs(aim, cur, total + 1);if (cur%prime2[total]) return;cur = cur / prime2[total];aim *= prime2[total];}}}int main(){Init();int Case = 0;while (cin >> n&&n){Case++;prime2.clear();for (int i = 0; i < prime.size() && (prime[i] - 1)*(prime[i] - 1) <= n; i++){if (n % (prime[i] - 1) == 0) prime2.push_back(prime[i]);}amount = prime2.size();ans = 200000000;memset(vis,0,sizeof(vis));dfs(1, n, 0);cout <<"Case "<<Case<<": "<<n<<" "<< ans << endl;}return 0;}


原创粉丝点击