您的位置:首页 > 其它

湖南2013第九届省赛解题报告(长期拖延更新中。。。)

2013-10-27 19:36 260 查看
偶尔做一题,做一题更新一题好了。。。

A、COJ1328: 近似回文词

转化的时候记录每个字母在原串位置,对新串枚举中点,向两边枚举判近似回文,更新更长回文。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
const int maxn = 111;
const double eps = 1e-10;
const double inf = 1e20;
const double pi = acos(-1.0);
inline double dcmp(double x){return (x > eps) - (x < -eps);}
inline double min(double a, double b) {return a < b ? a : b;}
inline double max(double a, double b) {return a > b ? a : b;}
inline double Sqr(double x) {return x * x;}
struct Point
{
double x, y;
Point(){x = y = 0;}
Point(double a, double b){x = a, y = b;}
inline Point operator-(const Point &b)const
{return Point(x - b.x, y - b.y);}
inline Point operator+(const Point &b)const
{return Point(x + b.x, y + b.y);}
inline Point operator*(const double &b)const
{return Point(x * b, y * b);}
inline double Dis(const Point &b)const
{return sqrt(Sqr(x - b.x) + Sqr(y - b.y));}
inline double cross(const Point &b, const Point &c)const
{return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
inline double dot(const Point &b)const
{return x * b.x + y * b.y;}
inline bool InLine(const Point &b, const Point &c)const
{return !dcmp(cross(b, c));}
inline bool OnSeg(const Point &b, const Point &c)const
{return InLine(b, c) && (*this - c).dot(*this - b) < eps;}
inline bool InSeg(const Point &b, const Point &c)const
{return InLine(b, c) && (*this - c).dot(*this - b) < -eps;}
};
bool SegCross(const Point &a, const Point &b, const Point &c, const Point &d)
{
return dcmp(a.cross(b, c) * a.cross(b, d)) < 0 && dcmp(c.cross(d, a) * c.cross(d, b)) < 0;
}
Point p[maxn];
int n;
double dp[maxn][maxn];
bool vis[maxn][maxn];
bool cancut[maxn][maxn];
double DPS(int start, int end)
{
double &ans = dp[start][end];
if(vis[start][end]) return ans;
vis[start][end] = true;
if(end - start <= 2) return ans = 0;
ans = inf;
int i;
if(cancut[start][end - 1])
ans = min(ans, DPS(start, end - 1) + p[start].Dis(p[end - 1]));
if(cancut[start + 1][end])
ans = min(ans, DPS(start + 1, end) + p[start + 1].Dis(p[end]));
for(i = start + 2; i < end - 1; i ++)
if(cancut[start][i] && cancut[i][end])
ans = min(ans, DPS(start, i) + DPS(i, end) + p[start].Dis(p[i]) + p[i].Dis(p[end]));
return ans;
}

bool InSimplePolygon(Point u, Point p[], int n)
{
int flag = 0;
for(int i = 0; i < n; i++)
{
Point p1 = p[i];
Point p2 = p[(i+1)%n];
if(u.OnSeg(p1, p2)) return false;
int k = dcmp(p1.cross(p2, u));
int d1 = dcmp(p1.y - u.y);
int d2 = dcmp(p2.y - u.y);
if(k > 0 && d1 <= 0 && d2 > 0) flag++;
if(k < 0 && d2 <= 0 && d1 > 0) flag--;
}
return flag != 0;
}
void InitCanCut()
{
memset(cancut, 0, sizeof(cancut));
for(int i = 0; i < n; i ++)
for(int j = i + 2; j < n; j ++)
{
if(i == 0 && j == n - 1) continue;
int k = n;
for(k = 0; k < n; k ++)
{
if(SegCross(p[i], p[j], p[k], p[k + 1]) || (k != i && k != j && p[k].InSeg(p[i], p[j])))
break;
}
if(k == n && InSimplePolygon((p[i] + p[j]) * 0.5, p, n)) cancut[i][j] = cancut[j][i] = true;
}
}

int main()
{
int ca = 0;
while(scanf("%d", &n) != EOF)
{
for(int i = 0; i < n; i ++)
scanf("%lf%lf", &p[i].x, &p[i].y);
p
= p[0];
InitCanCut();
memset(vis, 0, sizeof(vis));
printf("Case %d: %.4f\n", ++ca, DPS(0, n - 1));
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: