原题链接:http://codeforces.com/gym/102028/problem/E
解法:
打表找规律
可知分子1 2 6 30 210......
发现后一个等于前一个乘以2,3,5,7......
还可以发现分母1 3 12 72 576.。。。
发现后一个等于前一个乘以3,4,6,8......(也就是分子对应的质数加1)
那么接下来就是大数问题了
Java代码如下:(真的简短粗暴啊!)
1 //package 实验; 2 import java.math.BigInteger; 3 import java.util.Scanner; 4 import java.util.*; 5 import java.io.*; 6 import java.math.*; 7 public class Main { 8 static int[] p=new int[5050]; 9 static int[] p1=new int[5050]; 10 static int[] vis=new int[5050]; 11 static int cnt=0; 12 public static void init() { 13 for(int i=2;i<=5000;i++) { 14 if(vis[i]==1)continue; 15 p[++cnt]=i; 16 p1[cnt]=i+1; 17 for(int j=i;j<=5000;j+=i) { 18 vis[j]=1; 19 } 20 } 21 } 22 public static void main(String [] args){ 23 init(); 24 int T; 25 Scanner sc=new Scanner(System.in); 26 T=sc.nextInt(); 27 while(true) { 28 BigInteger n=sc.nextBigInteger(); 29 BigInteger x=BigInteger.valueOf(1); 30 BigInteger x1=BigInteger.valueOf(1); 31 BigInteger y=BigInteger.valueOf(1); 32 BigInteger y1=BigInteger.valueOf(1); 33 BigInteger z=BigInteger.valueOf(1); 34 for(int i=1;i<=cnt;i++) { 35 //System.out.println(x); 36 y=x; 37 y1=x1; 38 x=x.multiply(BigInteger.valueOf(p[i])); 39 x1=x1.multiply(BigInteger.valueOf(p1[i])); 40 if(n.compareTo(x)==-1)break; 41 } 42 z=y.gcd(y1); 43 y=y.divide(z); 44 y1=y1.divide(z); 45 System.out.println(y+"/"+y1); 46 T--; 47 if(T<=0)break; 48 } 49 sc.close(); 50 } 51 }
C++代码:(这个有点迷,计算客可以过,cf交上去过不了,慎用)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int L=5010; 5 string add(string a,string b) 6 { 7 string ans; 8 int na[L]={0},nb[L]={0}; 9 int la=a.size(),lb=b.size(); 10 for(int i=0;i<la;i++) na[la-1-i]=a[i]-‘0‘; 11 for(int i=0;i<lb;i++) nb[lb-1-i]=b[i]-‘0‘; 12 int lmax=la>lb?la:lb; 13 for(int i=0;i<lmax;i++) na[i]+=nb[i],na[i+1]+=na[i]/10,na[i]%=10; 14 if(na[lmax]) lmax++; 15 for(int i=lmax-1;i>=0;i--) ans+=na[i]+‘0‘; 16 return ans; 17 } 18 string mul(string a,string b) 19 { 20 string s; 21 int na[L],nb[L],nc[L],La=a.size(),Lb=b.size();//na存储被乘数,nb存储乘数,nc存储积 22 fill(na,na+L,0);fill(nb,nb+L,0);fill(nc,nc+L,0);//将na,nb,nc都置为0 23 for(int i=La-1;i>=0;i--) na[La-i]=a[i]-‘0‘;//将字符串表示的大整形数转成i整形数组表示的大整形数 24 for(int i=Lb-1;i>=0;i--) nb[Lb-i]=b[i]-‘0‘; 25 for(int i=1;i<=La;i++) 26 for(int j=1;j<=Lb;j++) 27 nc[i+j-1]+=na[i]*nb[j];//a的第i位乘以b的第j位为积的第i+j-1位(先不考虑进位) 28 for(int i=1;i<=La+Lb;i++) 29 nc[i+1]+=nc[i]/10,nc[i]%=10;//统一处理进位 30 if(nc[La+Lb]) s+=nc[La+Lb]+‘0‘;//判断第i+j位上的数字是不是0 31 for(int i=La+Lb-1;i>=1;i--) 32 s+=nc[i]+‘0‘;//将整形数组转成字符串 33 return s; 34 } 35 int sub(int *a,int *b,int La,int Lb) 36 { 37 if(La<Lb) return -1;//如果a小于b,则返回-1 38 if(La==Lb) 39 { 40 for(int i=La-1;i>=0;i--) 41 if(a[i]>b[i]) break; 42 else if(a[i]<b[i]) return -1;//如果a小于b,则返回-1 43 44 } 45 for(int i=0;i<La;i++)//高精度减法 46 { 47 a[i]-=b[i]; 48 if(a[i]<0) a[i]+=10,a[i+1]--; 49 } 50 for(int i=La-1;i>=0;i--) 51 if(a[i]) return i+1;//返回差的位数 52 return 0;//返回差的位数 53 54 } 55 string div(string n1,string n2,int nn)//n1,n2是字符串表示的被除数,除数,nn是选择返回商还是余数 56 { 57 string s,v;//s存商,v存余数 58 int a[L],b[L],r[L],La=n1.size(),Lb=n2.size(),i,tp=La;//a,b是整形数组表示被除数,除数,tp保存被除数的长度 59 fill(a,a+L,0);fill(b,b+L,0);fill(r,r+L,0);//数组元素都置为0 60 for(i=La-1;i>=0;i--) a[La-1-i]=n1[i]-‘0‘; 61 for(i=Lb-1;i>=0;i--) b[Lb-1-i]=n2[i]-‘0‘; 62 if(La<Lb || (La==Lb && n1<n2)) { 63 //cout<<0<<endl; 64 return n1;}//如果a<b,则商为0,余数为被除数 65 int t=La-Lb;//除被数和除数的位数之差 66 for(int i=La-1;i>=0;i--)//将除数扩大10^t倍 67 if(i>=t) b[i]=b[i-t]; 68 else b[i]=0; 69 Lb=La; 70 for(int j=0;j<=t;j++) 71 { 72 int temp; 73 while((temp=sub(a,b+j,La,Lb-j))>=0)//如果被除数比除数大继续减 74 { 75 La=temp; 76 r[t-j]++; 77 } 78 } 79 for(i=0;i<L-10;i++) r[i+1]+=r[i]/10,r[i]%=10;//统一处理进位 80 while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的 81 while(i>=0) s+=r[i--]+‘0‘; 82 //cout<<s<<endl; 83 i=tp; 84 while(!a[i]) i--;//将整形数组表示的余数转化成字符串表示的</span> 85 while(i>=0) v+=a[i--]+‘0‘; 86 if(v.empty()) v="0"; 87 //cout<<v<<endl; 88 if(nn==1) return s; 89 if(nn==2) return v; 90 } 91 bool judge(string s)//判断s是否为全0串 92 { 93 for(int i=0;i<s.size();i++) 94 if(s[i]!=‘0‘) return false; 95 return true; 96 } 97 string gcd(string a,string b)//求最大公约数 98 { 99 string t; 100 while(!judge(b))//如果余数不为0,继续除 101 { 102 t=a;//保存被除数的值 103 a=b;//用除数替换被除数 104 b=div(t,b,2);//用余数替换除数 105 } 106 return a; 107 } 108 int p[10005],vis[10005]; 109 char h[1000005]; 110 int cnt=0; 111 void init(){ 112 for(int i=2;i<=3000;i++){ 113 if(vis[i])continue; 114 p[++cnt]=i; 115 for(int j=i;j<=3000;j+=i){ 116 vis[j]=1; 117 } 118 } 119 } 120 void cal(int k){ 121 int c=0; 122 while(k>0){ 123 h[c++]=k%10+‘0‘; 124 k/=10; 125 } 126 h[c]=‘\0‘; 127 for(int i=0;i<c/2;i++){ 128 swap(h[i],h[c-i-1]); 129 } 130 } 131 int ok(string x,string y){ 132 if(x.length()>y.length())return 1; 133 else if(x.length()<y.length())return 0; 134 int len=x.length(); 135 for(int i=0;i<len;i++){ 136 if(x[i]>y[i])return 1; 137 if(x[i]<y[i])return 0; 138 } 139 return 1; 140 } 141 string m[500],m1[500]; 142 void init1(){ 143 string x="1"; 144 for(int i=1;i<=100;i++){ 145 cal(p[i]); 146 string y=(string)h; 147 x=mul(x,y); 148 m[i]=x; 149 } 150 } 151 void init2(){ 152 string x="1"; 153 for(int i=1;i<=100;i++){ 154 cal(p[i]+1); 155 string y=(string)h; 156 x=mul(x,y); 157 m1[i]=x; 158 } 159 } 160 int T; 161 string s; 162 int main() 163 { 164 init(); 165 init1(); 166 init2(); 167 cin.sync_with_stdio(false); 168 cin>>T; 169 while(T--){ 170 cin>>s; 171 if(s=="1"){ 172 printf("1/1\n"); 173 continue; 174 } 175 int id=0; 176 for(int i=1;i<=100;i++){ 177 if(!ok(s,m[i])){ 178 id=i-1; 179 break; 180 } 181 } 182 string z=gcd(m[id],m1[id]); 183 string x=div(m[id],z,1); 184 string y=div(m1[id],z,1); 185 cout<<x<<"/"<<y<<endl; 186 } 187 return 0; 188 }
原文地址:https://www.cnblogs.com/ccsu-kid/p/10101228.html
时间: 2024-11-08 21:50:12