JZOJ 3100. 国王游戏 NOIP2012
题目
分析
题目分析:
我们对于国王身后的两个点来分析
队列可能是这样的:
* | Left | Right |
---|---|---|
king: | a_0a0 | b_0b0 |
p1 | a_1a1 | b_1b1 |
p2 | a_2a2 | b_2b2 |
那么我们计算可得ans_1ans1=max(\frac{a_0}{b_1},\frac{a_0*a_1}{b_2})max(b1a0,b2a0∗a1)
队列也有可能是这样的
* | Left | Right |
---|---|---|
king: | a_0a0 | b_0b0 |
p2 | a_2a2 | b_2b2 |
p1 | a_1a1 | b_1b1 |
那么我们计算可得ans_2ans2=max(\frac{a_0}{b_2},\frac{a_0*a_2}{b_1})max(b2a0,b1a0∗a2)
我们来对比一下两个答案:
ans_1ans1=max(\frac{a_0}{b_1},\frac{a_0*a_1}{b_2})max(b1a0,b2a0∗a1)
ans_2ans2=max(\frac{a_0}{b_2},\frac{a_0*a_2}{b_1})max(b2a0,b1a0∗a2)
可以替换得:
ans_1ans1=max(k_1,k_2)max(k1,k2)
ans_2ans2=max(k_3,k_4)max(k3,k4)
显然我们可以得到:
\frac{a_0*a_1}{b_2}b2a0∗a1>\frac{a_0}{b_2}b2a0
\frac{a_0*a_2}{b_1}b1a0∗a2>\frac{a_0}{b_1}b1a0
即: k_2k2>k_3k3
k_4k4>k_1k1
如果ans_1ans1<ans_2ans2
那么易得:
k_4>k_2k4>k2
即: \frac{a_0*a_2}{b_1}b1a0∗a2>\frac{a_0*a_1}{b_2}b2a0∗a1
变形可得:
a_1*b_1<a_2*b_2a1∗b1<a2∗b2
当a_1*b_1<a_2*b_2a1∗b1<a2∗b2时,我们也能够得到ans_1ans1<ans_2ans2的结论
所以,为了ansans取到最小值,我们需要将a_i*b_iai∗bi较小的放在前面
那么我们以a_i*b_iai∗bi为关键字排序即可
同时,统计答案时一定不要忘了写高精度!
代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 struct sb 6 { 7 int l,r,cj; 8 }a[1001]; 9 bool cmp(sb a,sb b) 10 { 11 return a.cj<b.cj?true:false; 12 } 13 string minn="0"; 14 int f[10001]; 15 string x1; 16 void cf(int x) 17 { 18 for (int i=10000;i>=1;i--) 19 f[i]*=x; 20 for (int i=10000;i>=1;i--) 21 { 22 f[i-1]+=f[i]/10; 23 f[i]%=10; 24 } 25 int j=1; 26 while (f[j]==0) 27 j++; 28 x1=""; 29 for (int i=j;i<=10000;i++) 30 x1+=f[i]+'0'; 31 32 } 33 /*string div(string a,long long b) //神奇的高精除 34 { 35 string r,ans; 36 int d=0; 37 if(a=="0") return a; 38 for(int i=0;i<a.size();i++) 39 { 40 r+=(d*10+a[i]-'0')/b+'0'; 41 d=(d*10+(a[i]-'0'))%b; 42 } 43 int p=0; 44 for(int i=0;i<r.size();i++) 45 if(r[i]!='0') 46 { 47 p=i; 48 break; 49 } 50 return r.substr(p); 51 }*/ 52 int chu[10077],chu2[10077]; 53 string chuu(string a,int b) //普通高精除 54 { 55 string ans; 56 for (int i=0;i<a.size();i++) 57 chu[i+1]=a[i]-'0'; 58 int c=0; 59 for (int i=1;i<=a.size();i++) 60 { 61 chu[i]=chu[i]+(c*10); 62 c=chu[i]%b; 63 chu2[i]=chu[i]/b; 64 } 65 int j=1; 66 while (chu2[j]==0) j++; 67 for (int i=j;i<=a.size();i++) 68 ans+=chu2[i]+'0'; 69 return ans; 70 } 71 int main () 72 { 73 int n; 74 cin>>n; 75 int xx,y; 76 cin>>xx>>y; 77 for (int i=1;i<=n;i++) 78 { 79 cin>>a[i].l>>a[i].r; 80 a[i].cj=a[i].l*a[i].r; 81 } 82 sort(a+1,a+1+n,cmp); 83 f[10000]=1; 84 cf(xx); 85 for (int i=1;i<=n;i++) 86 { 87 string ans=chuu(x1,a[i].r); 88 if (ans.size()!=minn.size()) //字符比较大小要先让位数一样 89 { 90 if (ans.size()>minn.size()) 91 { 92 string t; 93 for (int i=1;i<=ans.size()-minn.size();i++) 94 t+="0"; 95 t+=minn; 96 minn=t; 97 t=""; 98 } 99 else 100 { 101 string t; 102 for (int i=1;i<=minn.size()-ans.size();i++) 103 t+="0"; 104 t+=ans; 105 ans=t; 106 t=""; 107 } 108 109 } 110 if (ans>minn) 111 minn=ans; 112 cf(a[i].l); 113 } 114 cout<<minn; 115 }