“玲珑杯”线上赛 Round #17 河南专场 A: Sin your life(和化积公式)
传送门
题意
略
分析
首先将sin(x)+sin(y)+sin(z)h转化成\(2*sin(\frac{x+y}2)*cos(\frac{x-y}2)+sin(z)\),而cos(z)=cos(-z)
1.x+y为偶数,那么x-y为偶数,且如果x+y=i,那么x-y可取的值为0,2...,i-2
2.x+y为奇数,那么x-y为奇数,切如果x+y=i,那么x-y可取的值为1,3...,i-2
那么在x+y为偶数的时候,直接取x-y为0;在x+y为奇数的时候,设一个mxodd记录从1到i-2的cos的最大值。
从0到n-1扫一遍,遇到奇数更新,并计算max值,遇到偶数直接计算max值,复杂度\(O(n)\)
trick
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
//#pragma comment(linker, "/STACK:102400000,102400000")
inline void read(int &x){x=0; char ch=getchar();while(ch<'0') ch=getchar();while(ch>='0'){x=x*10+ch-48; ch=getchar();}}
const double pi = acos(-1.0);
//double d[3003000];
int n;
double mxodd;
int main()
{
//d[3]=cos(0.5);
//for(int i=5;i<=3000000;i+=2) d[i]=max(d[i-2],cos((i-2)*1.0/2));
while(scanf("%d",&n)==1)
{
double ans=0,mxodd=-1e9;
for(int i=2;i<=n-1;++i)
{
if(i&1)
{
mxodd=max(mxodd,cos((i-2)/2));
ans=max(ans,2*sin(i*0.5)*mxodd+sin(n-i));
}
else ans=max(ans,2*sin(i*0.5)+sin(n-i));
}
printf("%.9f\n",ans);
}
return 0;
}
一直地一直地往前走