题目:https://cn.vjudge.net/problem/UVALive-6471
题意:一个n边形的三角剖分是指用n-3条不相交的内对角线,把一个n边形分成n-2个三角形。三角剖分的三角数目序列指的是,依次列出与每个顶点相连的三角形数目组成的序列。
给出一份长度为n的三角数目序列,判断这个序列是否符合是一个n边形的三角数目序列。如果符合,输出所有三角形的顶点编号,并按字典序排列。
思路:可以从递归的思想考虑。在三角剖分中,必定有一个三角形是由邻近三个顶点组成的。这三个顶点中间的那个点的三角数目必定为一。如果从原图形去掉这个三角形,剩下的部分是一个n-1边形。
就这样每次找到序列中为1的一个顶点,然后去掉这个三角形,直到只剩下三个点,显然这时序列应为(1, 1, 1),每次删去三角形时判断不合法的情况,顺便记录删去的三角形的顶点序号。
代码:c++11
#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <algorithm>
using namespace std;
vector<vector<int> > triangle;
list<pair<int, int> > datalist;//index, cnt
int n;
bool check()
{
while(datalist.size() > 3)
{
vector<int> vt;
list<pair<int, int> >::iterator it = datalist.begin();
bool ok = false;
for(; it != datalist.end(); it++)
{
if(it->second == 1)
{
ok = true;
break;
}
}
if(!ok)
{
return false;
}
vt.push_back(it->first);
if(it == datalist.begin())
{
if(--datalist.back().second)
{
vt.push_back(datalist.back().first);
}
else
{
return false;
}
auto iter = it;
iter++;
if(--iter->second)
{
vt.push_back(iter->first);
}
else
{
return false;
}
}
else if(it->first == datalist.back().first)
{
if(--datalist.front().second)
{
vt.push_back(datalist.front().first);
}
else
{
return false;
}
auto iter = it;
iter--;
if(--iter->second)
{
vt.push_back(iter->first);
}
else
{
return false;
}
}
else
{
auto iter = it;
iter--;
if(--iter->second)
{
vt.push_back(iter->first);
}
else
{
return false;
}
iter = it;
iter++;
if(--iter->second)
{
vt.push_back(iter->first);
}
else
{
return false;
}
}
triangle.push_back(vt);
datalist.erase(it);
}
vector<int> vt;
for(auto t : datalist)
{
if(t.second != 1)
{
return false;
}
vt.push_back(t.first);
}
triangle.push_back(vt);
return true;
}
int main()
{
int T;
cin >> T;
while(T--)
{
int cases;
scanf("%d%d", &cases, &n);
datalist.clear();
triangle.clear();
for(int i = 1; i <= n; i++)
{
int a;
scanf("%d", &a);
datalist.push_back(make_pair(i, a));
}
if(!check())
{
printf("%d N\n", cases);
}
else
{
printf("%d Y\n", cases);
for(int i = 0; i < triangle.size(); i++)
{
sort(triangle[i].begin(), triangle[i].end());
}
sort(triangle.begin(), triangle.end());
for(int i = 0; i < triangle.size(); i++)
{
for(int j = 0; j < 3; j++)
{
if(j != 0)
{
printf(" ");
}
printf("%d", triangle[i][j]);
}
printf("\n");
}
}
}
}
本文介绍了一种算法,用于验证给定的三角数目序列是否符合一个n边形的三角剖分特性。通过递归地查找序列中为1的顶点,逐步去除对应的三角形,最终确定序列的有效性并输出所有三角形的顶点编号。

被折叠的 条评论
为什么被折叠?



