2023年程序设计竞赛基础实训22
解不等式
printf直接输出数字                             
其中m为从键盘输入的正整数,式中符号为二个“+”号后一个“-”号,即分母能被3整除时为“-”。
输入正整数m,输出满足不等式的n。
测试数据: (1) m=4  (2) m=7
设计要点1:
式中出现减运算,导致不等式的解也许分段。
设立条件循环,每三项(包含二正一负)一起求和,得一个区间解。
然后回过头来一项项求和,得个别离散解。
为叙述方便,记
(1)通过循环知s(d+1)>m,且n=d+1为“-”,可得n=d为一个解;
而n=d+2时1.0/(n+3)为“+”,可得s(d+2)>m;以后各项中,“-”项小于其前面的“+”项,可知对于n>d+2有s(n)>m成立。
因而有区间解:n≥d
(2)在n<d时是否有解,逐个求和检查拟定离散解。这一步不能省,否则出现遗解。
程序设计1:
//  解不等式:m<1+1/2-1/3+1/4+1/5-1/6+...+-1/n
#include <stdio.h>
void main()
{ long d,n,m,k; double s;
  printf("\n  请输入m: "); scanf("%d",&m);
  n=-2;s=0;
  while(s<=m)
    { n=n+3;s=s+1.0/n+1.0/(n+1)-1.0/(n+2); }
  d=n+1; s=0;                            // 可拟定区间解n≥d(1)
  for(k=1;k<=n;k++)
    { if(k%3>0) s=s+1.0/k;
      else s=s-1.0/k;
      if(s>m) printf("  n=%ld, ",k);    // 逐个得离散解   
    }
  printf("n>=%ld \n",d);         
}
程序运营示例:
  请输入m: 4
  n=10151, n=10153, n>=10154
  请输入m: 7
  n=82273511, n=82273513, n>=82273514
注意:要特别注意,不要把离散解遗失。
思考:假如把后一个离散解写入区间解中?
设计要点2:
为叙述方便,记
(1)  通过循环累加,当加到s=s+1.0/n+1.0/(n+1)-1.0/(n+2);得s(n+2)>m,令d=n+1,可知:n≥d为解;
(2)  此时,s(n)有也许大于m,因而在原s基础上s-1.0/d+1.0/(d+1)得s(n):
若s(n)>m,合并得区间解:n≥d-1;
若s(n)<m,区间解为:n≥d;(因可肯定s(n-1)<m)
但s(n-2)尚有也许大于m,因而在上s基础上s+1.0/(d-2)-1.0/(d-1),得s(n-2):
若s(n-2)>m, 得一个离散解:n=d-3;
若s(n-2)<m, 没有离散解
程序设计2:
//  解不等式:m<1+1/2-1/3+1/4+1/5-1/6+...+-1/n
#include <stdio.h>
void main()
{ long d,n,m; double s;
  printf("\n  请输入m: "); scanf("%d",&m);
  n=-2;s=0;
  while(s<=m)
    { n=n+3;s=s+1.0/n+1.0/(n+1)-1.0/(n+2); }
  d=n+1;                              // 可拟定区间解n≥d(1)
  s=s-1.0/d+1.0/(d+1);                // 得s(n)
  if(s>m) printf("  n>=%ld \n",d-1);  // 输出区间解
  else printf("  n>=%ld \n",d);
  s=s+1.0/(d-2)-1.0/(d-1);            // 得s(n-2)
  if(s>m) printf("  n=%ld \n",d-3);    // 输出一个离散解         
}
数据测试:
  请输入m: 4
n>=10153
n=10151
  请输入m: 7
n>=82273513
n=82273511
程序设计3:请判断以下程序是否对的?
//  解不等式:m<1+1/2-1/3+1/4+1/5-1/6+...+-1/n
#include <stdio.h>
void main()
{ double n,m,s;
  printf("\n  请输入m: "); scanf("%lf",&m);
  n=0;s=3.0/2;
  while(s<=m)
    { n=n+3;s=s-1.0/n+1.0/(n+1)+1.0/(n+2); }
  d=n+2;
  printf(" n=%.0f,",d);                // 得一个离散解(1)
  s=s-1.0/(n+3)+1.0/(n+4);d=n+4;
  if(s>m) printf("  n>=%.0f\n",d);    //  可拟定区间解n≥d(2)
  else printf("  n>=%.0f\n",d+1);      //  ??
}
(1) 一方面s(d)>m,n=d为一个解;
而s(d-3)<=m,n=d-2为“-”项,其绝对值大于n=d-1的“+”项,可得s(d-1)<m;且知n<d时无解。
同时由,可得s(d+1)<m,即n=d为一个离散解。
(2) 当s(n+4)>m时,以后的“-”项绝对值小于其前面的“+”项,故得区间解n≥d;
当s(n+4)<=m时,因可知s(n+5)>m;但不能拟定s(n+6)>0,因而不能拟定n≥d+1为区间解!
求最大值
设指定区间[a,b]内的正整数x,y,z,w满足
 
其中a≤x<y<z<w≤b,试求s=x+y+z+w的最大值。
输入正整数a,b(1≤a<b<10000), 输出s的最大值。