UVa 1331 Minimax Triangulation

本文详细阐述了如何使用最优三角剖分算法对多边形进行分割,通过状态表示及转移,有效计算出多边形中最大三角形的最小面积。
部署运行你感兴趣的模型镜像

Triangulation of surfaces has applications in the Finite Element Method of solid mechanics. The objective is to estimate the stress and strain on complex objects by partitioning them into small simple objects which are considered incompressible. It is convenient to approximate a plane surface with a simple polygon, i.e., a piecewise-linear, closed curve in the plane on m distinct vertices, which does not intersect itself. A chord is a line segment between two non-adjacent vertices of the polygon which lies entirely inside the polygon, so in particular, the endpoints of the chord are the only points of the chord that touch the boundary of the polygon. A triangulation of the polygon, is any choice of m -3 chords, such that the polygon is divided into triangles. In a triangulation, no two of the chosen chords intersect each other, except at endpoints, and all of the remaining (unchosen) chords cross at least one of the chosen chords. Fortunately, finding an arbitrary triangulation is a fairly easy task, but what if you were asked to find the best triangulation according to some measure?

Input 

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing one positive integer 2 < m < 50, being the number of vertices of the simple polygon. The following m lines contain the vertices of the polygon in the order they appear along the border, going either clockwise or counter clockwise, starting at an arbitrary vertex. Each vertex is described by a pair of integers x y obeying 0 ≤ x ≤ 10 000 and 0 ≤ y ≤ 10 000.

Output 

For each scenario, output one line containing the area of the largest triangle in the triangu-lation of the polygon which has the smallest largest triangle. The area should be presented with one fractional decimal digit.

Sample Input 

1
6
7 0
6 2
9 5
3 5
0 3
1 1

Sample Output 

9.0

#include <cstdio>
#include <cmath>
#include <utility>
#include <cstring>
#include <algorithm>
using namespace std;

// 记录点
pair<int,int> point[60];

// 点的个数
int n;

// record[i][j]代表多边形i,i+1,...,j进行三角剖分最大三角形的最小面积 
double record[55][55];

// flag[i][j]代表record[i][j]是否被计算过
int flag[55][55];

double get_min(int i, int j);

double get_area(int i, int j, int k);

int main()
{
	int t;
	scanf("%d", &t);
	int count = 0;
	while(count < t)
	{
		memset(flag, 0, sizeof(flag));
		scanf("%d", &n);
		for(int i = 0; i < n; i++)
		{
			scanf("%d %d", &point[i].first, &point[i].second);
		}
		// 计算结果
		printf("%.1f\n", get_min(0,n-1));
		count++;		
	}	
	return 0;
}

// 计算多边形:i,i+1,...,j三角剖分最大三角形的最小面积
double get_min(int i, int j)
{
	if(flag[i][j] == 1)
		return record[i][j];

	if(i+1 == j)
	{
		flag[i][j] = 1;
		record[i][j] = 0;
		return record[i][j];
	}	
	
	record[i][j] = 1<<30;
	for(int k = i+1; k < j; k++)
	{

		double area = get_area(i, j, k);
		// 首先需要保证i,j,k可围成三角形,即没有点在三角形内
		int m;
		for(m = 0; m < n; m++)
		{
			if(m != i && m != j && m != k)
			{
				double a1 = get_area(i, j, m);
				double a2 = get_area(i, k, m);
				double a3 = get_area(j, k, m);
				if(fabs((a1+a2+a3)-area) < 1e-5)
					break;
			}
		}
		if(m == n)
		{
			double r = max(get_min(i,k), get_min(k,j));
			r = max(r, area);
			if(r < record[i][j])
				record[i][j] = r;
		}

	}	
	flag[i][j] = 1;
	return record[i][j];	
}

// 计算三点围成的三角形面积
double get_area(int i, int j, int k)
{

	double a = sqrt((point[i].first-point[j].first)*(point[i].first-point[j].first)
                                +(point[i].second-point[j].second)*(point[i].second-point[j].second));
      	double b = sqrt((point[i].first-point[k].first)*(point[i].first-point[k].first)
                                +(point[i].second-point[k].second)*(point[i].second-point[k].second));
	double c = sqrt((point[k].first-point[j].first)*(point[k].first-point[j].first)
                                +(point[k].second-point[j].second)*(point[k].second-point[j].second));

      	double p = (a+b+c)/2;

    	double area = sqrt(p*(p-a)*(p-b)*(p-c));

	return area;
}


和最优三角剖分类似,对于多边形i,i+1,...,j来说,总要从i+1,...,j-1中选择一个点来形成三角形。以此进行状态表示及转移。
需要注意的是,此处没有规定多边形为凸多边形,有可能选择的三个点不能构成三角形,即有其他点在该三角形中。
判断点k是否在三角形abc中,可以用三角形面积abk+bck+ack是否等于abc来判断。

另外,这题WA了很久,发现是在主程序中另外定义了一个局部变量n. 以后需要注意局部变量和全局变量重名引起的错误。

您可能感兴趣的与本文相关的镜像

HunyuanVideo-Foley

HunyuanVideo-Foley

语音合成

HunyuanVideo-Foley是由腾讯混元2025年8月28日宣布开源端到端视频音效生成模型,用户只需输入视频和文字,就能为视频匹配电影级音效

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
MiniMax是一家中国科技公司,一直致力于进行大模型相关的研究。它是国内AI独角兽企业,旗下有多款产品,在AI领域展现出较强实力。 ### 产品介绍 - **海螺视频**:这是MiniMax推出的一款AI创意视频平台,凭借强大的AI视频生成能力和简单易用的操作界面,吸引了众多关注。它不仅能让用户轻松生成高清的2K视频,还能创作专属的AI音乐,让用户在AI创作的世界里尽情挥洒创意[^1]。 ### 应用场景 - **视频创作**:海螺视频为视频创作者提供了便利,能快速生成高质量的2K视频,满足创作者对于视频内容的创意需求,节省创作时间和成本[^1]。 - **大模型对接**:从代码示例可知,可将OpenAI与MiniMax进行对接,使用MiniMax的模型进行对话交互等操作,拓展了大模型的应用场景,例如在智能客服、智能聊天等领域的应用[^2]。 ### 特点 - **强大的技术实力**:MiniMax一直专注于大模型相关研究,其自研的MM智能助理是一款没有调用其他产品接口的大型语言模型,体现了公司在大模型研发方面的技术积累和创新能力[^2]。 - **产品功能丰富**:以海螺视频为例,除了基本的视频生成功能外,还具备AI音乐创作能力,为用户提供了更全面的创意创作工具,满足多样化的需求[^1]。 - **资本青睐**:获得阿里领投的6亿美元融资,这表明其在市场上具有较高的认可度和发展潜力,充足的资金也有助于公司进一步开展研发和拓展业务[^3]。 ### 代码示例 以下是OpenAI对接MiniMax的代码示例: ```python from openai import OpenAI client = OpenAI( api_key="xxx", base_url="https://api.minimax.chat/v1", ) completion = client.chat.completions.create( model="abab6.5s-chat", messages=[ {"role": "system", "content": "MM智能助理是一款由MiniMax自研的,没有调用其他产品的接口的大型语言模型。MiniMax是一家中国科技公司,一直致力于进行大模型相关的研究。"}, {"role": "user", "content": "你好"} ] ) print(completion) print("Trace-ID:", completion.id) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值