从零单排2

文章详细记录了大学期间学习贪心算法与计算几何的基础知识,包括三角形面积计算、多边形重心求法、简单排序算法、贪心算法经典题目以及高等数学中的微积分应用。通过实例解析,展示了如何使用贪心算法解决实际问题,并对二分查找法进行了实践。此外,还涉及了计算几何中多边形重心的计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

八点钟搞到现在,11点的时候要去上体育课,贪心这一块比较重要,下午计组课后到晚上这段时间用来好好做一做贪心的题目吧~

下面是刚刚进行的练习

3. 计算几何初步
a) 三角形面积  hdu 2036
b) 三点顺序  //三点顺序就是简单的矢量差乘,这里换成了练习求多边形重心 hdu 1115
4. 学会简单计算程序的时间复杂度与空间复杂度 //这就不用多说了吧。。
5. 二分查找法 hdu 2199 2899
6. 简单的排序算法 hdu 2020
a) 冒泡排序法
b) 插入排序法
7. 贪心算法经典题目
8. 高等数学 hdu 1071微积分。。。

以下为题解

hdu 2036:http://acm.hdu.edu.cn/showproblem.php?pid=2036

/*
计算几何第一题~
1A
A=sigma |xi      yi    | /	2
		|x(i+1)  y(i+1)|/
*/ 

#include<iostream>
#include<cmath>
using namespace std;
struct Point
{
	double x;
	double y;
};
Point point[105];
double triangle(double x1,double y1,double x2,double y2)
{
	return fabs(x1*y2-x2*y1);
}
int main()
{
	int n;
	while(cin>>n&&n)
	{
		double ans=0;
		for(int i=1;i<=n;i++)
		{
			cin>>point[i].x>>point[i].y;
		}
		for(int i=1;i<=n-1;i++)
		{
			ans+=triangle(point[i].x,point[i].y,point[i+1].x,point[i+1].y);
		}
		ans+=triangle(point[n].x,point[n].y,point[1].x,point[1].y);
		printf("%.1lf\n",ans/2);
	}
	system("pause");
	return 0;
}
hdu 1115: http://acm.hdu.edu.cn/showproblem.php?pid=1115

/*
求多边形重心
要注意这里triangle不应该带绝对值

C=sigma((pi+pi+1)(pi X pi+1))/(6A)
*/
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
struct Point
{
	double x;
	double y;
	double s;
};
Point point[1000005];
double triangle(double x1,double y1,double x2,double y2)
{
	return x1*y2-x2*y1;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		double x=0;
		double y=0;
		double s=0;
		double ans=0;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>point[i].x>>point[i].y;
		}
		for(int i=1;i<=n-1;i++)
		{
			point[i].s=triangle(point[i].x,point[i].y,point[i+1].x,point[i+1].y);
			s+=point[i].s/2;
			x+=point[i].s*(point[i].x+point[i+1].x);
			y+=point[i].s*(point[i].y+point[i+1].y);
		}
		point[n].s=triangle(point[n].x,point[n].y,point[1].x,point[1].y);
		s+=point[n].s/2;
		x+=point[n].s*(point[n].x+point[1].x);
		y+=point[n].s*(point[n].y+point[1].y);
		x=x/(6*s);
		y=y/(6*s);
		printf("%.2lf %.2lf\n",x,y);
	}
	system("pause");
	return 0;
}
			

hdu 2199: http://acm.hdu.edu.cn/showproblem.php?pid=2199

/*
二分查找
注意精度的控制
一开始MIN为1e-6的时候结果不对
改为1e-7后AC
*/
#include<iostream>
#include<cmath>
#define MIN 1e-7
using namespace std;
double fun(double x,double y)
{
	return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6-y;
}
int main()
{
	int T;
	double y;
	cin>>T;
	while(T--)
	{
		cin>>y;
		if(fun(0,y)>0||fun(100,y)<0)
		{
			cout<<"No solution!"<<endl;
			continue;
		}
		else
		{
			double left=0;
			double right=100;
			double mid;
			while(right-left>MIN)
			{
				mid=(left+right)/2;
				if(fun(mid,y)>0)
				{
					right=mid-MIN;
				}
				else
				{
					left=mid+MIN;
				}
			}
			mid=(left+right)/2;
			printf("%.4lf\n",mid);
		}
	}
	system("pause");
	return 0;
}
			
	

hdu 2899: http://acm.hdu.edu.cn/showproblem.php?pid=2899

/*
还是二分查找
最小值点即导函数零点
同时注意单调情况的判断
1A~
*/
#include<iostream>
#include<cmath>
#define MIN 1e-6
using namespace std;
double fun1(double x,double y)
{
	return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x;
}
double fun2(double x,double y)
{
	return 42*pow(x,6)+48*pow(x,5)+21*pow(x,2)+10*x-y;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		double y;
		cin>>y;
		if(fun2(0,y)>0)
		{
			printf("%.4lf\n",fun1(0,y));
		}
		else if(fun2(100,y)<0)
		{
			printf("%.4lf\n",fun1(100,y));
		}
		else
		{
			double left=0;
			double right=100;
			double mid;
			while(right-left>MIN)
			{
				mid=(left+right)/2;
				if(fun2(mid,y)>0)
				{
					right=mid-MIN;
				}
				else
				{
					left=mid+MIN;
				}
			}
			mid=(left+right)/2;
			printf("%.4lf\n",fun1(mid,y));
		}
	}
	system("pause");
	return 0;
}

hdu 2020: http://acm.hdu.edu.cn/showproblem.php?pid=2020

/*
练习冒泡排序和插入排序
输出因为最后一个数据后面没有空格问题得了一个pe
分别用两种排序方法A了一次
*/
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
struct data
{
	int prev;
	int now;
};
data a[105];
void print(data a[],int n)
{
	for(int i=0;i<n;i++)
	{
		cout<<a[i].prev;
		if(i!=n-1)
			cout<<" ";//空格问题wa了一次 
	}
	cout<<endl;
}
void bubblesort(data a[],int n)
{
	int flag=1;
	for(int i=0;i<n-1;i++)
	{
		if(!flag)
			break;
		for(int j=i+1;j<n;j++)
		{
			if(a[j].now>a[i].now)
			{
				flag=1;
				swap(a[i],a[j]);
			}
		}
	}
	print(a,n);
}
void insertsort(data a[],int n)
{
	int i,j;
	for(i=1;i<n;i++)
	{
		data temp=a[i];
		for(j=i-1;j>=0&&a[j].now<temp.now;j--)
		{
			a[j+1]=a[j];
		}
		a[j+1]=temp;
	}
	print(a,n);
}	
int main()
{
	int n;
	while(cin>>n&&n)
	{
		for(int i=0;i<n;i++)
		{
			cin>>a[i].prev;
			a[i].now=fabs(a[i].prev);
		}
//		bubblesort(a,n);
		insertsort(a,n);
	}
	system("pause");
	return 0;
}

hdu 1071: http://acm.hdu.edu.cn/showproblem.php?pid=1071

/*
算是高等数学题吧。。。
这里注意顶点式求二次函数a的时候的方法
y1=a(x-x1)^2+c
这里不要用两个点做差求a,容易产生除数为0的情况
应该直接代入(x2,y2)来求 
*/
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
double fun(double a,double b,double c,double x1,double x2)
{
	return (a*pow(x2,3)+b*pow(x2,2)+c*x2)-(a*pow(x1,3)+b*pow(x1,2)+c*x1);
} 
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		double x1,y1,x2,y2,x3,y3;
		cin>>x1>>y1;
		cin>>x2>>y2;
		cin>>x3>>y3;
		double h=x1;
		double c=y1;
		double a=(y2-c)/pow(x2-x1,2); 
		double k=(y3-y2)/(x3-x2);
		double b=y2-x2*k;
		double index1=a/3;
		double index2=a*h*(-1)-k/2;
		double index3=a*pow(h,2)+c-b;
		printf("%.2lf\n",fun(index1,index2,index3,x2,x3));
	}
	system("pause");
	return 0;
}
		

二分的题目还是比较多的,这里只练习了两道最基本最裸的二分题目,以后遇到与其他方法结合的二分题目再做整理。

等到把大一上的内容整理完之后再系统的做一遍那个链接中数学和贪心的大一上的题目~

嗯~

加油~!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值