数学竞赛
Time Limit: 1000 ms Memory Limit: 256 MB
Description
Portal -->
(那个qwq这个题面真的是太长了qwq所以还是传送一波比较好qwq)
Sample Input
111111000
1/2
Sample Output
63616161
HINT
打开一个科学计算器,依次按下\(arctan\)(或\(tan^{−1}\))、 \(cos\) 、 \(arctan\)、 \(sin\) 、\(arctan\) 、 \(sin\) 、\(arctan\) 、 \(sin\),会得到 \(0.5\) 。
Solution
抱歉OI真的不只是信息竞赛
- 10%
这个是读题分吧qwq,能用7操作(也就是+1)且分母为1那就直接加就好了,\(p=q\)的时候先\(arctan\)一下然后再\(cos\)一下就好了
比较坑的是。。要分清楚当前到底是角度还是长度。。。(就是因为初始是长度且值为0所以才要先\(arctan\)一下不能直接\(cos\))
- 30%
大力构造一波,反过来从\(\frac{p}{q}\)推回\(0\),那就是用7和8操作,如果当前分数大于1那就减一(也就是执行一步7操作到当前),小于1就取倒数(也就是执行一步8操作到当前),记录一路上的操作最后反着输出就好了
(其他pts不太会qwq)
- 100%
正解的做法很优美啊qwq(疯狂%sk大佬)
现在我们不能用7,8,9这三个友善的操作了qwq而是要去面对一堆三角函数。。。然而如果有7和8操作的话整个求解过程就十分简单了
那么就。。考虑能否用三角函数组合起来达到7和8操作的效果,也就是\(x=x+1\)和\(x=\frac{1}{x}\)的效果
\(x+1\)不太好搞,那先看\(x=\frac{1}{x}\)
会发现
所以先\(sin\)一下\(arccos\)一下,再\(arctan\)一下就可以得到倒数了
然而还是不能搞出\(x=x+1\),那就搞一下9操作也就是\(x=\sqrt{x^2+1}\)咯。。(长得像个勾股式的样子)
然而还是不能搞出\(x=x+1\)
但是!如果说我们维护的是\(\sqrt{x}\),9操作其实就是将\(\sqrt{x}\)变成了\(\sqrt{x+1}\),也就是说当我们只考虑\(\sqrt{x}\)的时候,上面的两条式子就是取倒数和加一两种操作(!!!)
那么,我们只要用上面的两种操作,沿用30%子任务中的构造方式,求出\(\frac{p^2}{q^2}\)就好了
(抱歉我是真的想不到qwq哇真的sk太强了疯狂%%%)
题外话:然而yxq巨佬用spfa碾过了这题对没错spfa(因为\(p\)和\(q\)的范围很小啊),也是全部换成根号考虑,顺利有理化qwq
代码大概长这样
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[10];
int p,q;
void solve(int p,int q);
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
char ch;
scanf("%s",s);
scanf("%d%c%d",&p,&ch,&q);
if (p==0) return 0;
p*=p; q*=q;
solve(p,q);
}
void solve(int p,int q){
if (p==q){
printf("63");
return;
}
int tmp=0;
while (p>=q) p-=q,++tmp;
if (p){
solve(q,p);
printf("6145");
}
for (int i=1;i<=tmp;++i) printf("636145");
}