前言
本文旨在用C++解决问题:“用二分法求方程的解。”以及解决VS 2017 中报错问题:C4996 'scanf':this function or variable may be unsafe.
一、题目描述
给出等式 8x4+7x3+2x2+3x+6=y 8 x 4 + 7 x 3 + 2 x 2 + 3 x + 6 = y ,能在x属于[0,100]之间找到方程的解吗?
输入的第一行包含一个整数T(1≤T≤100),表示测试用例的数目。接着有T行,每行有一个实数y
(|y|≤1e10
(
|
y
|
≤
1
e
10
)。
对于每组测试用例,如有解,则输出解(实数),反之输出“no solution”。
二、解题思路
方程的等式左边在[0,100]这个区间明显是个单调递增函数,即满足二分的性质,所以直接用二分枚举x,即可求解。
三、C++源码
#include<iostream>
//#include<cstdlib> //这里可有可无
using namespace std;
//cstdlib的本来面目是C语言中的库stdlib.h 。在C++中,C语言中的一些库被进行了重命名,去掉了.h并在库名前加c。比如: C语言
//中的stdlib.h在C++被重命名为cstdlib C语言中的ctype.h在C++中被重命名为cctype C语言中的stdio.h在C++中被重命名为
//cstdio C语言中的time.h在C++中被重命名为ctime。
//题目:给出一个等式,用二分法求方程的解。
const double precision = 1e-8; //这个表示还是很神奇的,表示10的-8次方。
//一个简单函数:求方程左边的式子的值
double func(double x) {
return (8 * x*x*x*x + 7 * x*x*x + 2 * x*x + 3 * x + 6);
}
int main() {
int num; //接受的测试用例数目
scanf("%d", &num);
double left, right, mid; //[0,100]的区间,所以left一开始是0,right是100. mid是用在二分法中的变量
double y; //方程等式右边的y值,作为测试用例的输入。
while (num--) { //对每个测试用例输入进行求解。
left = 0;
right = 100; //初始化 区间的左右边界值
scanf("%lf", &y);//接受输入
if (y<func(0) || y>func(100)) { //因为等式左边是个递增函数,所以判断是不是在上下界中,不在自然就无解。
printf("No solution!\n");
}
else { //这是有解的情况,进行二分法求解。
while (right - left > precision) {
mid = (right + left) / 2;
if ((func(mid) - y) > 0) { //如果是正值,自然是把right的值改成mid啦。
right = mid;
}
else {
left = mid; //反之让left的值变成mid,不断缩小区间,直到right和left的距离小于等于precision
}
}
printf("%.4lf\n", left);
}
}
system("pause");
return 0;
}
四、运行结果
五、总结
1)复习了一下二分法;
2)明白了cstdlib是什么;
3)一开始的时候一直报错:
C4996 'scanf':this function or variable may be unsafe.
解决方案:在程序的第一行加入代码#define _CRT_SECURE_NO_WARNINGS
即可。