Blue Bridge Cup brush title 5 -- dance of Sine
1 topic
Title: Dance of Sine
Problem description
Recently, FJ has set up a mathematical analysis course for his cows. FJ knows that if he wants to learn this course well, he must have a good basic skill of trigonometric function. So he is going to play a game of "dance of Sine" with the cows to improve their computing power.
We might as well set
An=sin(1–sin(2+sin(3–sin(4+...sin(n))...)
Sn=(...(A1+n)A2+n-1)A3+...+2)An+1
FJ wants the cows to calculate the value of Sn. Please help FJ print out the complete expression of SN to facilitate the cows to do the problem.
Input format
Only one number: n < 201.
Output format
Please output the corresponding expression Sn, ending with a line break. The output must not contain extra spaces or line breaks or carriage returns.
sample input
3
sample output
((sin(1)+3)sin(1–sin(2))+2)sin(1–sin(2+sin(3)))+1
2. Solutions
2.1 A(n)
You can see that there are multiple A(n) in S(n). Let's finish the construction of A(n). Use recursive methods.
In order to make it convenient for every recursive function to modify a string, I set str as static. Of course, it is necessary to initialize str before calculating A(n). Here is my first thought (forget to think about the sign).
public class Main { public static StringBuilder str; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.close(); str = new StringBuilder(); A(n); System.out.println(str); } public static void A(int n) { if(n==0) { str.deleteCharAt(0); return; } else { str.insert(0, n); str.insert(0, "-sin("); str.append(')'); A(--n); } } }
But I think it's not good enough, because S(n) calls to A(n) are incremental calls from 1 to n. Of course, I can calculate A(n) every time, but it would be better if I could make A(n) use A(n-1). But now I'm using this method to apply layer by layer on both sides of a string, so that A(2) cannot be calculated on the basis of A(1). So I plan to recurse from 1 to N, and insert the next layer of string in the middle of the string.
So with the title, it's better to write A(n). In fact, A(n) is not recursive.
public class Main { public static StringBuilder str; public static void main(String[] args) { // Test A(1) to A(4) A(1); System.out.println(str); A(2); System.out.println(str); A(3); System.out.println(str); A(4); System.out.println(str); } public static void A(int i) { if(i == 1) str = new StringBuilder("sin(1)"); else if(i%2==0) str.insert(str.length() - i + 1, String.format("-sin(%d)", i)); else str.insert(str.length() - i + 1, String.format("+sin(%d)", i)); } }
The results are as follows, which is exactly what I want.
sin(1) sin(1-sin(2)) sin(1-sin(2+sin(3))) sin(1-sin(2+sin(3-sin(4))))
2.2 S(n)
It's quite simple to deal with S(n) again and analyze it a little.
StringBuilder sn = new StringBuilder(); for(int i=1;i<n;i++) sn.append('('); // Add the left bracket first for(int i=1;i<=n;i++) { A(i); // Calculate once A(n) sn.append(str); //Add A(n) sn.append(String.format("+%d)", n+1-i)); // Add following characters } sn.deleteCharAt(sn.length()-1); // Remove the last extra closing parenthesis System.out.println(sn);
3 complete code
This time, it's OK. I don't feel like I made a detour like I did last time. 125ms,33.18MB.
import java.util.Scanner; public class Main { public static StringBuilder str; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); scanner.close(); StringBuilder sn = new StringBuilder(); for(int i=1;i<n;i++) sn.append('('); for(int i=1;i<=n;i++) { A(i); sn.append(str); sn.append(String.format("+%d)", n+1-i)); } sn.deleteCharAt(sn.length()-1); System.out.println(sn); } public static void A(int i) { if(i == 1) str = new StringBuilder("sin(1)"); else if(i%2==0) str.insert(str.length() - i + 1, String.format("-sin(%d)", i)); else str.insert(str.length() - i + 1, String.format("+sin(%d)", i)); } }