题解:P17237 『STA - R10』介电常数

· · 题解

现有的题解太防御性了,给一个人类的做法(

Part I

我们需要用三角函数与乘法实现 a+b

这一问能带给你的本质观察是:由于我们可以使用三角函数的逆运算,我们随时可以将元在 xf(\theta) 间进行转换。这就给了我们很大的操作空间。

三角函数中加法与乘法的转换,我们能想到的是 1-\cos2\alpha=2\sin^2\alpha。这样我们就解决了子问题:给定 x,计算 1-x

进一步可以利用 \tan 的性质,我们有 \tan=\frac{\sin}{\cos},这能帮我们实现将第一个数化为 1。稍加推导可以得到这样一个方案:

a+b\to \cos(\alpha+\beta)\to \cos\alpha\cos\beta(1-\tan\alpha\tan\beta)\to 1-x

于是第一部分解决。

Part II

第一步自然是将两个变量独立开,化成 \frac{(a+b)^2-a^2-b^2}2。于是我们要解决这两个子问题:

  1. 给定 x,计算 x^2
  2. 给定 x,计算 x/2

前者仍然套用二倍角公式:

后者看上去比较棘手。不过,没有乘法自然也意味着,三角函数的和差相关公式基本可以不考虑了,而没有这些公式必然难以处理 /2。所以考虑转为给定 x 计算 1/x。而三角函数里本身就有 \cot=\frac1\tan,直接计算即可。

:::info[Code]

#include <bits/stdc++.h>

using namespace std;

int T;

int main() {
    scanf("%d", &T);
    if (T == 1) {
        puts("15"); 
        puts("3 1 cos");
        // 3: cos a
        puts("3 2 cos");
        // 4: cos b
        puts("3 1 tan");
        // 5: tan a
        puts("3 2 tan");
        // 6: tan b
        puts("2 5 6");
        // 7: x = tan a*tan b
        // calc 1-x: 1-x=1-cos(acos(x)/2*2)=2*sin^2(acos(x)/2)
        puts("0 0.5");
        // 8: 1/2
        puts("0 2");
        // 9: 2
        puts("3 7 acos");
        // 10: acos(x)
        puts("2 10 8");
        // 11: acos(x)/2
        puts("3 11 sin");
        // 12: sin(acos(x)/2)
        puts("2 12 12");
        // 13: sin^2(acos(x)/2)
        puts("2 13 9");
        // 14: 2*sin^2(acos(x)/2)=1-x
        puts("2 3 4");
        // 15: cos a*cos b
        puts("2 14 15");
        // 16: cos(a+b)
        puts("3 16 acos");
        // 17: a+b
    } else {
        puts("20");
        puts("1 1 2");
        // 3: a+b
        // calc 2x^2-1=2cos^2(acos(x))-1=cos(2acos(x))
        puts("3 3 acos");
        // 4: acos(x)
        puts("1 4 4");
        // 5: 2acos(x)
        puts("3 5 cos");
        // 6: cos(2acos(x))=2x^2-1
        // calc 1-2x^2=1-2sin^2(asin(x))=cos(2asin(x)
        puts("3 1 asin");
        // 7: asin(a)
        puts("1 7 7");
        // 8: 2acos(a)
        puts("3 8 cos");
        // 9: cos(2asin(a))=1-2a^2
        puts("3 2 asin");
        // 10: asin(b)
        puts("1 10 10");
        // 11: 2acos(b)
        puts("3 11 cos");
        // 12: cos(2asin(b))=1-2b^2
        puts("0 -1");
        // 13: -1
        puts("1 6 9");
        // 14: 2(a+b)^2-2a^2
        puts("1 14 12");
        // 15: 2(a+b)^2-2a^2-2b^2+1
        puts("1 15 13");
        // 16: 2(a+b)^2-2a^2-2b^2=x
        // calc x/4=1/(4/x)
        puts("3 16 atan");
        // 17: atan(x)
        puts("3 17 cot");
        // 18: cot(atan(x))=1/x
        puts("1 18 18");
        // 19: 2/x
        puts("1 19 19");
        // 20: 4/x
        puts("3 20 atan");
        // 21: atan(4/x)
        puts("3 21 cot");
        // 22: cot(atan(4/x))=x/4
    }
}

:::