B题-求素数
思路
数据太多,暴力会超时,所以先打表就好啦。
代码
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
int a[16001];
int main()
{
for(int i=3;i<=16000;i+=2){
int j;
if(i%2==0)
break;
for(j=3;j<=i/2;j+=2)
if(i%j==0)
break;
if(j>i/2)
a[i]=1;
}
int i=1,n;
while(cin>>n&&n>0){
cout<<i++<<": ";
if(a[n])
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}
C题
思路
根据这样那样的物理公式一通乱搞得出y = x*tan(a)-(1+tan(a)*tan(a))*(g*x*x)/(2*v*v)
然后用三分求出公式中角a的最大值,最后用二分具体求出角a
代码
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define g 9.8
#define exps 1e-8
#define PI acos(-1)
double x,y,v;
#define fll(a) x*tan(a)-(1+tan(a)*tan(a))*(g*x*x)/(2*v*v)
int main()
{
int n;
cin>>n;
while(n--){
cin>>x>>y>>v;
double le=0,ri=PI/2.0,lmid,rmid;
while(fabs(ri-le)>exps){
lmid=(ri+le)/2;
rmid=(ri+lmid)/2;
if(fll(lmid)>fll(rmid))
ri=rmid;
else le=lmid;
}
if(fll(ri)<y){
cout<<"-1"<<endl;
continue;
}
double mid;
le=0;
mid=(le+ri)/2;
while(fabs(fll(mid)-y)>exps){
mid=(ri+le)/2;
if(fll(mid)>y) ri=mid;
else le=mid;
}
printf("%.6lf\n",mid);
}
return 0;
}
D题
思路
找到每个矩形的最左边和最右边,计算出矩形的大小然后找到最大的。
找最左边与最右边用的是DP,比第i个高的能选择的边界i一定能达到。
代码
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
long long a[100010],l[100010],r[100010],n;
void getl(){
for(int i=1;i<n;i++){
int ll=i;
while(ll-1>=0&&a[ll-1]>=a[i]) ll=l[ll-1];
l[i]=ll;
}
return;
}
void getr(){
r[n-1]=n-1;
for(int i=n-2;i>=0;i--){
int rr=i;
while(rr+1<n&&a[rr+1]>=a[i]) rr=r[rr+1];
r[i]=rr;
}
return;
}
int main()
{
while(cin>>n&&n){
for(int i=0;i<n;i++)
cin>>a[i];
getl();getr();
long long sum=(r[0]-l[0]+1)*a[0];
for(int i=1;i<n;i++)
if(sum<(r[i]-l[i]+1)*a[i])
sum=(r[i]-l[i]+1)*a[i];
cout<<sum<<endl;
}
return 0;
}