2018焦作区域赛E. Resistors in Parallel

Posted ccsu-kid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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]=;
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
");
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 }

 













以上是关于2018焦作区域赛E. Resistors in Parallel的主要内容,如果未能解决你的问题,请参考以下文章

2018ACM-ICPC焦作区域赛反思总结

2018焦作网络赛K

2018焦作网络赛E

2018焦作网络赛J

2018焦作网络赛B

2018焦作网络赛L