程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> zoj3658 Simple Function (函數值域)

zoj3658 Simple Function (函數值域)

編輯:C++入門知識

Simple Function

--------------------------------------------------------------------------------

Time Limit: 2 Seconds      Memory Limit: 32768 KB

--------------------------------------------------------------------------------

Knowing that x can be any real number that x2 + Dx + E ≠ 0. Now, given the following function

y = f(x) = Ax2 + Bx+ C
-------------------
x2 + Dx + E
 

What is the range of y.

Input
The first line contains a single integer T (T ≤ 10000), indicating that there are T cases below.

Each case contains five integers in a single line which are values of A, B, C, D and E (-100 ≤ A, B, C, D, E ≤ 100).

Output
For each case, output the range of y in the form of standard interval expression like in a single line.

The expression is made up by one interval or union of several disjoint intervals.

Each interval is one of the following four forms: "(a, b)", "(a, b]", "[a, b)", "[a, b]"(there is a single space between ',' and 'b'), where a, b are real numbers rounded to 4 decimal places, or "-INF" or "INF" if the value is negative infinity or positive infinity.

If the expression is made up by several disjoint intervals, put the letter 'U' between adjacent intervals. There should be a single space between 'U' and nearby intervals.

In order to make the expression unique, the expression should contain as minimum of intervals as possible and intervals should be listed in increasing order.

See sample output for more detail.

Sample Input
5
1 1 1 2 3
0 1 0 1 -10
-3 -1 0 -1 -1
0 0 0 0 0
1 3 0 2 0
Sample Output
[0.3170, 1.1830]
(-INF, INF)
(-INF, -1.8944] U [-0.1056, INF)
[0.0000, 0.0000]
(-INF, 1.0000) U (1.0000, 1.5000) U (1.5000, INF) 關於求值域,在高中學了很多方法,在這裡我不推薦通過移項再根據x來算Δ>=0的方法來求y的值域,我之前就是這樣寫的,因為這樣算出來的Δ值可能有很多種,而且意義不明確(如果數學功底不夠就看不出來),太過麻煩,最後討論分母為0去斷點時也很麻煩 下面講解時修改別人的,因為他的跟我的有點出入。題目大意:描述起來很簡單,求f(x) = (Ax^2 + Bx + C) / (x^2 + Dx + E)的值域。解題思路:分子分母都含有自變量x,不好處理。最簡單的想法就是把分子上的自變量消去。(二次->一次->零次)。然後就是各種情況討論。1.二次->一次f(x) =  (Ax^2 + Bx + C) / (x^2 + Dx + E)=  A + (bx + c) / (x^2 + Dx + E) (其中b=B-A*D, c=C-A*E)=  A + g(x)這樣我們把分子的二次項消除了。注意之後的結果區間都要加上A。2.一次-> 零次(1) 若B = 0。那麼g(x) = c / (x^2 + Dx + E)(a)如果c=0。則值域為[0, 0].(b)如果c!=0。則此時分母的式子是一個開口向上的拋物線,設其極小值為mins,則取值區間為[mins, INF).此時需要對mins和c的正負情況討論才能寫出正確區間。(mins的正負即表示Δ)c>0時mins>0  值域為 (0, c/mins].mins>0  值域為 (0, INF].mins<0  值域為 (-INF, c/mins] U (0, INF)c<0時同上分析,區間顛倒下就可以了。(2) 若b != 0。那麼g(x) = (bx + c) / (x^2 + Dx + E)要消去一次項,我們可以換元,令t=b*x + c得到g(t) = b*b*t / (t^2 + bb*t + cc)   其中bb=D*b-2*c,cc=(c*c+E*b*b-D*b*c);(1)如果t取0,則g(t)=0;(2)當t!=0時 g(x) =b*b/(t+cc/t + bb) = h(t)此時要求h(t)= b*b/(t+cc/t + bb)的值域(t!=0)。只有分母有自變量,非常好求解了。注意最後要把0點補回去。(i) cc<0 時。t+cc/t 能取遍(-INF, INF)。所以值域的為(-INF, INF)。(ii) cc>0 時。t+cc/t 的值域為(-INF, 2√cc] U [2√cc, INF)故分母的值域為(-INF, 2√cc+bb] U [2√cc+bb, INF)全部的值域易得。我這裡不需要討論分子分母的正負號,但是需要確定區間的范圍,細心點就好了,詳見代碼吧。

#include<stdio.h> 
  #include<math.h>     int main()  {      int T;  
    double A,B,C,D,E,a,b,c,bb,cc,x1,x2,temp1,temp2,y1,mins;  
    scanf("%d",&T);   
   while(T--)      {          scanf("%lf%lf%lf%lf%lf",&A,&B,&C,&D,&E);    
      a=A;          b=B-A*D;     
     c=C-A*E;   
       mins=E-D*D/4;//分母拋物線的極大值     
      if(b==0)//f(x)=A+((B-A*D)*x+C-A*E)/(x*x+D*x+E),f(x)=a+(b*x+c)/(x*x+D*x+E)    
       {              if(c==0)                  printf("[%.4f, %.4f]\n",A,A);   
           else if(c>0)              {                  if(mins>0)                
      printf("(%.4f, %.4f]\n",A,c/mins+A);      
            else if(mins<0)       
               printf("(-INF, %.4f] U (%.4f, INF)\n",c/mins+A,A);         
         else printf("(%.4f, INF)\n",A);       
       }              else               {                  if(mins>0)            
          printf("[%.4f, %.4f)\n",c/mins+A,A);        
          else if(mins<0)                      printf("(-INF, %.4f) U [%.4f, INF)\n",A,c/mins+A);         
         else printf("(-INF, %.4f)\n",A);        
      }          }          else //b!=0情況,f(x)=A+b*b/(t+(c*c+E*b*b-D*b*c)/t+D*b-2*c)           {              x1=-c/b;          

    if(x1*x1+D*x1+E==0)//排除那種分子分母有公因式的情況    
           {                  x2=-D-x1;                  if(x1==x2)           
           printf("(-INF, %.4f) U (%.4f, INF)\n",A,A);            
      else                  {//(b*(x-x1))/((x-x1)*(x-x2))    
                   y1=b/(x1-x2);               
       if(y1>0)                          printf("(-INF, %.4f) U (%.4f, %.4f) U (%.4f, INF)\n",A,A,A+y1,A+y1);               
       else          
                 printf("(-INF, %.4f) U (%.4f, %.4f) U (%.4f, INF)\n",A+y1,A+y1,A,A);       
           }              }              else              {                  bb=D*b-2*c;     
             cc=(c*c+E*b*b-D*b*c);            
      if(cc>0)//分母化成了g(t)=t+cc/t+bb,t=b*x+c,分子變成了b*b,所以不用考慮分子的符號了               
    {                      temp1=2.0*sqrt(cc);             
         temp2=temp1+bb;//這便是分母的極大值                       temp1=-temp1+bb;//分母的極小值    
                   if(temp1>0)//極小值大於0     
                      printf("(-INF, %.4f] U [%.4f, INF)\n",A+b*b/temp2,A+b*b/temp1);    
                  else if(temp1==0)//極小值為0                   
        printf("(-INF, %.4f]\n",A+b*b/temp2);                      else if(temp2<0)//極大值小於0                           printf("(-INF, %.4f] U [%.4f, INF)
\n",A+b*b/temp2,A+b*b/temp1);                
      else if(temp2==0)//極大值為0                           printf("[%.4f, INF)\n",A+b*b/temp1);           
           else printf("[%.4f, %.4f]\n",A+b*b/temp1,A+b*b/temp2);        
          }                  else if(cc<0)                      printf("(-INF, INF)\n");         
         else                       printf("(-INF, INF)\n");      
        }          }      }      return 0;  }  

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved