数学竞赛

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}\)

  会发现

\[\begin{aligned} &arctan(90^\circ -x)=\frac{1}{x}\\ &90^\circ-x=arccos(sin(x)) \end{aligned} \]

  所以先\(sin\)一下\(arccos\)一下,再\(arctan\)一下就可以得到倒数了

  

  然而还是不能搞出\(x=x+1\),那就搞一下9操作也就是\(x=\sqrt{x^2+1}\)咯。。(长得像个勾股式的样子)

\[\begin{aligned} \frac{1}{\sqrt{x^2+1}}&=cos(arctan(x))\\ \sqrt{x^2+1}&=\frac{1}{cos(arctan(x))}\\ \end{aligned} \]

  然而还是不能搞出\(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");
}
posted @ 2018-04-18 17:34  yoyoball  阅读(190)  评论(0)    收藏  举报