1. 程式人生 > >2018焦作區域賽E. Resistors in Parallel

2018焦作區域賽E. Resistors in Parallel

原題連結: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 }