习题

题目一

题目

有形如:a x^3 + b x^2 + c x + d = 0a**x3+b**x2+c**x+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,da,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 -100−100 至 100100 之间),且根与根之差的绝对值 \ge 1≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 22 位。

提示:记方程 f(x) = 0f(x)=0,若存在 22 个数 x_1x1 和 x_2x2,且 x_1 < x_2x1<x2,f(x_1) \times f(x_2) < 0f(x1)×f(x2)<0,则在 (x_1, x_2)(x1,x2) 之间一定有一个根。

根有可能是

暴力法

#include<stdio.h>
int main()//这个方法感觉运气成分比较大
{
	double a,b,c,d;
	double qj(double x)
	{
		return a*x*x*x+b*x*x+c*x+d;
	}
	int s=0;
	scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
	for(double i=-100;i<=100;i+=0.001)
	{
		double r=i+0.001;
		
		if(qj(i)*qj(r)<0)
		{		
		printf("%.2lf ",i);
		s++;
        }
        if(s==3)break;
	}
	return 0;
 } 

二分法

#include<stdio.h>
double a,b,c,d;
double js(double x) {
	return a*x*x*x+b*x*x+c*x+d;
}
int main() {
	double l,r,x1,x2,m;
	int s=0;
	scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
	for(int i=-100; i<=100; i++) {
		l=i;
		r=i+1;
		x1=js(l);
		x2=js(r);
		if(!x1) {
			printf("%.2lf " ,l);
			s++;
		}
		if(x1*x2<0) {
			while((r-l)>=0.001) //控制精度
            {
				m=(l+r)/2;
				if(js(m)*js(r)<=0)l=m;
				else r=m;
			}
			printf("%.2lf ",r);
			s++;
		}
		if(s==3)break;
	}
	return 0;
}

题目二

用卡特兰数

#include<stdio.h>
#define siz 20
int main()
{
	int n;
	int a[siz*2][siz];
	scanf("%d",&n);
	for(int i=1;i<=2*n;i++)
	{
		a[i][1]=a[i][i]=1;
	}
	for(int i=3;i<=2*n;i++)
	{
		for(int j=2;j<i;j++)
		{
			a[i][j]=a[i-1][j]+a[i-1][j-1];
		}
	}
	printf("%d",a[2*n][n]-a[2*n][n-1]);
	return 0;
}

木材加工

题目背景

要保护环境

题目描述

木材厂有 $n$ 根原木,现在想把这些木头切割成 $k$ 段长度为 $l$ 的小段木头(木头有可能有剩余)。

当然,我们希望得到的小段木头越长越好,请求出 $l$ 的最大值。

木头长度的单位是 $\text{cm}$,原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。

例如有两根原木长度分别为 $11$ 和 $21$,要求切割成等长的 $6$ 段,很明显能切割出来的小段木头长度最长为 $5$。

输入格式

第一行是两个正整数 $n,k$,分别表示原木的数量,需要得到的小段的数量。

接下来 $n$ 行,每行一个正整数 $L_i$,表示一根原木的长度。

输出格式

仅一行,即 $l$ 的最大值。

如果连 $\text{1cm}$ 长的小段都切不出来,输出 0

样例 #1

样例输入 #1

3 7
232
124
456

样例输出 #1

114

提示

数据规模与约定

对于 $100%$ 的数据,有 $1\le n\le 10^5$,$1\le k\le 10^8$,$1\le L_i\le 10^8(i\in[1,n])$。

#include<stdio.h>
int arr[100000];
int n,k;
int check(int len)//检查长度能切割的数目
{
	int cnt=0;
	for(int i=0;i<n;i++)
	{
		cnt+=arr[i]/len;
	 } 
	 if(cnt>=k)return 1;
	 else return 0;
 } 
 
 int cz(int l,int r)
 {
 	if(r-l<=1)
 	{
 		if(check(r))
 		return r;
 		else if(check(l))
 		return l;
 		else return 0;
	 }
	 int mid=(l+r)/2;
	 if(check(mid))return cz(mid,r);
	 else return cz(l,mid);
 }

int main()
{
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)
{
	scanf("%d",&arr[i]);
}
printf("%d",cz(1,10000000));
	return 0;
 } 
posted @ 2022-05-22 17:38  孟夏十二  阅读(53)  评论(0编辑  收藏  举报