给定一系列介于0和1之间的所有有理数(0 / 1,1 / 1,1 / 2,1 / 3,2 / 3,...,n / d)打印第k个分数< / p>
我已经使用了他们的调试器,我的程序会输出他们给出的完全相同的答案,但法官仍然认为它不正确。
我使用Euler's totient function找到分母并迭代通过等于1的GCD来找到分子。据我所知,这应该足够了。
任何帮助都将不胜感激。
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <math.h>
using namespace std;
//Calculate the greatest common divisor of a and b
long long GCD(long long a, long long b){
if (a == 0){
return b;
}
return GCD(b%a, a);
}
int main(){
long long input;
vector <long long> inputVector;
vector <long long> phiValues;
long long totient;
long long total;
int numerator;
int denominator;
while(cin >> input){
if(input == 0){
break;
}
inputVector.push_back(input);
}
// Calculate phi for all integers from 1 to
// 20000 and store them
for(int i = 1; i <= 200000; i++){
long long current = i;
totient = current;
for(long long k = 2; k <= sqrt(i); k++){
if(current % k == 0){
totient -= totient / k;
while(current % k == 0){
current /= k;
}
}
}
if(current > 1){
totient -= totient / current;
}
phiValues.push_back(totient);
}
for(int i = 0; i < inputVector.size(); i++){
long long N = inputVector[i];
total = 1;
for(int j = 0; j <= phiValues.size(); j++){
if(total >= N){
if(N == 1){ //For the case of N = 1
denominator = 1;
}else{
denominator = j;
}
total -= phiValues[j-1];
break;
}
total += phiValues[j];
}
int index = 0;
for(int j = 1; j <= denominator; j++){
if(GCD(j, denominator) == 1){
index++;
if(index == N - total){
numerator = j;
break;
}
}
}
cout << numerator << '/' << denominator << endl;
}
return 0;
}
答案 0 :(得分:0)
Here @jte表示可以在O(N*logN)
中实现PHI的计算:
phi[0] = phi[1] = 0;
for (int i=2; i<maxn; ++i)
phi[i] = i - 1;
for (int i=1; i<maxn; ++i)
for (int j=i+i; j<maxn; j+=i)
phi[j] -= phi[i];
我找不到你的代码问题。可能是TLE(超出时间限制)问题,因为你应该使用二分搜索来找到分母。但是这段代码将获得ACCEPTED:
#include<bits/stdc++.h>
using namespace std;
const int N = 200031;
int pr[N+31],phi[N+31];
vector<int> P[N+31];
long long S[N+31];
int count(int n,int X)
{
int res=n;
int N=P[X].size();
for (int mask=1;mask<(1<<N);mask++) {
int C=0;
int prod=1;
for (int j=0;j<N;j++)
if (mask&(1<<j))
C++,
prod*=P[X][j];
if (C%2)
res-=n/prod;
else
res+=n/prod;
}
return res;
}
int solve(int need,int val)
{
int l,r;
l=1;
r=val;
while (l<r) {
int mid=l+r;
mid/=2;
int Q=count(mid,val);
if (Q>=need)
r=mid;
else
l=mid+1;
}
return l;
}
int main()
{
ios_base::sync_with_stdio(0);
pr[1]=1;
for (int i=1;i<=N;i++) {
if (pr[i])
continue;
for (int j=i;j<=N;j+=i)
P[j].push_back(i),
pr[j]=1;
}
for (int i=1;i<=N;i++) {
phi[i]=i;
for (int j=0;j<P[i].size();j++) {
int val=P[i][j];
phi[i]=phi[i]/val*(val-1);
}
}
for (int i=1;i<=N;i++)
S[i]=S[i-1]+phi[i];
long long x;
while (cin>>x) {
if (x==0)
break;
--x;
if (x==0)
{
cout<<0<<"/"<<1<<endl;
continue;
}
int id=lower_bound(S+1,S+N+1,x)-S;
x-=S[id-1];
int ps=solve(x,id);
cout<<ps<<"/"<<id<<endl;
}
return 0;
}