sine之舞
问题描述 :不妨设
An=sin(1–sin(2+sin(3–sin(4+…sin(n))…)
Sn=(…(A1+n)A2+n-1)A3+…+2)An+1
输入格式 仅有一个数:N<201。
输出格式 请输出相应的表达式Sn,以一个换行符结束。输出中不得含有多余的空格或换行、回车符。
样例输入3
样例输出((sin(1)+3)sin(1–sin(2))+2)sin(1–sin(2+sin(3)))+1
起初,看到题目毫无思路,题目要求上说的是递归,递推,所以刚开始直接思考的是递归(可能是出于对递归的心理阴影),所以很迷茫,自己先是以为只要简单的递归就可以了。后来在网上百度了大佬的代码,经过仔细研究,再加上看题目给的输入输出模式和范例,发现这道题就是一个递推式:
先看An,这是一个妥妥的递推啊。(i从1开始)
//a1=sin(1) //a2=sin(1-sin(2)//a3=sin(1-sin(2+sin(3)))//ai=sin(1 偶数-;奇数+ sin(2 偶数-;奇数+ sin(3 … i个右括号----)
再看Sn,这是一个妥妥的建立在An上的递推啊。
//s1=a1+1//s2=(a1+2)a2+1//s3=((a1+3)(a2+2))a3+1
//si=[i-1]个左括号a1+i)(a2+i-1)…(ai-1+2))ai +1
那么,本题的思路就是下面的:
先用主函数输入n的值,然后开始输出的函数的调用;
输出时,先根据n的值,判断最前面有几个“(”,然后开始A1~An连着相乘的输出。需要注意的是,函数An部分,如果n=1,则a1=sin(1)即可,其他情况关系到要有前边的符号问题,所以分为奇偶数的情况对待:偶数为-,奇数位+。另外,由于是一个递推式,每一个an中,处理sin(n)之外,前边的部分斗鱼an-1相同,所以在输出an的时候,不可避免地要调用An函数,这就是解体的递归部分(递归:函数在计算的过程中对自身进行调用)。而在Sn部分,除了刚开始的“(”的输出,函数An的调用之外,还有sn的输出过程中,每个ai后需要+n+1-i的问题,但是需要主义的是,对于sn,当输出到an时,最后+1后没有“)”。所以,在最后的an输出时,应该和前边的部分分开,重新写一个函数小模块。那么,最后的“)”,就得放在an的输出后边。最后实现+1。以下是借鉴大佬代码,看懂之后,自己用自己的理解敲出来的部分:
#include<stdio.h>
int a(int n)
{
if(n==1)
printf("sin(1");
else
if(n%2==0)
{
a(n-1);//递归调用,输出前边的内容
printf("-sin(%d",n);
}
else
if(n%2==1)
{
a(n-1);//递归调用,输出前边的内容
printf("+sin(%d",n);
}
return 0;
}
int s(int n)
{
int i,j,k;
//先输出,最靠前边的(
for(i=1;i<=n-1;i++)
printf("(");
//输出sn内部的内容
for(i=1;i<n;i++)
{
a(i);
//输出括号----sin后的括号
for(j=1;j<=i;j++)
printf(")");
printf("+%d)",n+1-i);//输出的是----+n+1-i)
//因为最后的i==n时,输出的+1后边不需要),所以应将n==i对的情况拿出来单独写
}
//将特殊的情况,单独拿出来,写一段针对特定对象的代码
a(n);
for(i=1;i<=n;i++)
printf(")");
printf("+1");
return 0;
}
int main()
{
int n;
scanf("%d",&n);
s(n);//开始调用函数
return 0;
}