D. Keiichi Tsuchiya the Drift King
theme:一辆车的长为b,宽为a,现经过一个内圆半径为r,弧度为d的弯角,车在直道贴着路内道行驶,在弯道始终沿着切线方向行驶。问道路宽度至少为多少才能保证车顺利通过?0<a,b,r<100 ,0<d<180。
solution:两种情况。(1)若弧度比较大,车可以完全进入弯道,则考虑左上角刚好与外道相交的情形为宽度最小值。由于方向为切线方向,所以下图中OA在一条直线上,长度为a+r,而OB为r+道路宽度w,可知求出OB即可求w,而OB^2=AB^2+OA^2
(2)若弧度较小,可能左上角恰好与直道相交地往切线方向行驶,之后就进入了直道保证不会超过道路线。这时图中标注位置角度为d。答案则是红线部分-r,红线部分为先求出蓝线长度,再求出sin值即可
#include<bits/stdc++.h>
using namespace std;
#define far(i,t,n) for(int i=t;i<n;++i)
#define pb(a) push_back(a)
#define lowbit(x) x&(-x)
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
double pi=acos(-1);
int inf=0x3f3f3f3f;
int mod=1e9+7;
const int maxn=100010;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b,r,d;
scanf("%d%d%d%d",&a,&b,&r,&d);
double tana=1.0*b/(a+r);
double dis=sqrt(1.0*b*b+(a+r)*(a+r));
double ans;
if(d>=90||tan(d*pi/180)>=tana)
ans=dis-r;
else
ans=1.0*(a+r)*cos(d*pi/180)+b*sin(d*pi/180)-r;
printf("%.12f\n",ans);
}
return 0;
}
E. Resistors in Parallel
theme:n个电阻,第i个电阻为i,特别的,当i为d^2的倍数,d>=2时,第i个电阻为无穷大。现选择一种分组si,将si中电阻进行并联,要求si中的电阻j满足j是i的因数,求并联后最小电阻。
solution:并联电路电阻计算公式:。电阻最小,所以我们希望分母越大。当i为d^2的倍数,可知并联后倒数为0.将i分解质因数为i=p0^b1 * p1^b2...之后,可发现若存在bj>=2,则i可被d^2整除,所以我们要使分母大,就尽可能在<=n范围内找到更多的质数相乘(即bj=1),又值越小倒数越大,所以当然按2,3,4,7的顺序乘。所以问题转化为找到x=2*3*5*7...的数,且x<=n,则sx即为电阻最小的选择。由于n可到10^100,所以筛出100个质数用大整数即可确定x可分解的质数个数。确定x后,分组sx的电阻应为
/
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541};
int t;
Scanner input=new Scanner(System.in);
t=input.nextInt();
while (t!=0) {
--t;
BigInteger n;
n=input.nextBigInteger();
BigInteger now=BigInteger.ONE;
int idx=-1;
for(int i=0;i<100;++i){
String s=Integer.toString(prime[i]);
now=now.multiply(new BigInteger(s));
if(now.compareTo(n)>0)
break;
idx=i;
}
if(idx==-1)
System.out.println("1/1");
else if(idx==0)
System.out.println("2/3");
else {
BigInteger up=BigInteger.ONE;
BigInteger down=BigInteger.ONE;
for(int i=0;i<=idx;++i){
up=up.multiply(BigInteger.valueOf(prime[i]));//up
down=down.multiply(BigInteger.valueOf(prime[i]+1));//down
}
BigInteger gcd=up.gcd(down);
up=up.divide(gcd);
down=down.divide(gcd);
System.out.println(up+"/"+down);
}
}
}
}