IAC(Incoming ACM/ICPC Contests) 0.1 Beta 发布

18 评论162次阅读2008.02.26 0:32 作者:Felicia 编辑

[阅读更多]

最近学了点 php 和 MySQL,想做个东西练练手。于是就写了个自动获取最新的 ACM 比赛的程序。目前版本是 0.1 Beta,功能正在不断完善中。

有兴趣的网友可以点击最近比赛页面,查看由我的程序自动获取的最近比赛列表。
(全文 …)

标签, , | 日志分类:网络技术

ZOJ Monthly, February 2008 总结

9 评论67次阅读2008.02.24 23:44 作者:Felicia 编辑

[阅读更多]

这次比赛 GCC 只能说是发挥得一般。一共出了5个题,排名第9。感觉上还 1007 应该能出的。如果做出6题,排名能到第4,那就很好了。

这次比赛有两个题目比较好:1007 和 1009。1007 没能 AC。1009 经过我和 mmd 的讨论,最后 AC 了。
(全文 …)

Vista 下 Apache + MySQL + php 安装手记

4 评论6次阅读2008.02.23 21:14 作者:Felicia 编辑

[阅读更多]

因为使用 WordPress 的 Blog 系统,不免会碰到一些 php 问题,也想自己写一些 php 程序,所以在本本上安装了 Apache + MySQL + php 的 Web 开发平台。在 Vista 下安装这些东西挺麻烦的,网上有很多相关的文章,但大都解决不了问题。我参考了一些文章,把过程总结一下。

  1. 安装环境
    操作系统是 Windows Vista Ultimate 中文版, Apache, PHP, MySQL 的最新版本可以在其官网下载的:
  2. 安装的目录结构规划
    为了方便维护,以及重装系统时不必进行二次安装,建议不要将其安装在系统盘(默认是 C 盘),例如我是装在 F 盘。安装路径也最好不要含有空格和中文字符。
    我的目录结构规划如下:
    <F:>
    |--<WWW>
    |   |--<SERVER>        # 安装 Web 服务程序
    |   |   |--<Apache>    # Apache安装目录
    |   |   |--<MySQL>     # MySql安装目录
    |   |   |--<PHP>       # PHP安装目录
    |   |
    |   |--<Web>     # 网站内容
    |   |   |--<test.php>
    |   |   |--<其它PHP程序>
    

    下面的安装说明的举例,以上列目录结构为准。

  3. 在 Windows Vista 下安装 Apache 2.2.8

    Windows Vista 下的安装,主要是由于 UAC 权限的影响,有可能导致服务无法安装成功。但这并不要紧,可以手工解决

    1. 运行 Apache 2.2.8 的安装程序,根据提示一路 Next 即可。注意在 Server InformationNetwork Domain、Server Name 字段填上 localhost,在安装类型的位置选 Custom,然后改变安装路径(我的目录是 F:WWWSERVERApache)。然后根据提示一路 Next 完成即可。
    1. 进入 DOS 窗口后,执行下列命令
      # 进入 Apache 的安装目录
      C:windowssystem32> f:
      F:> cd f:WWWSERVERApachebin
      # 安装 Apache 服务:
      F:WWWSERVERApachebin> httpd -k install
      #启动  Apahce 服务
      F:WWWSERVERApachebin> httpd -k start
    2. 我是用迅雷下载的 Apache 安装程序。安装好了之后一直无法启动 Apache 服务。遇到这种状况,一般是 80 端口被占用了。看一下占用端口的进程,果然是迅雷把 80 端口占用了。关掉迅雷之后,就可以正常启动 Apache 服务了。
  4. 在 Windows Vista 下安装 php 5.2.5
    1. 将下载的 php 5 ZIP 包直接解压,我直接将 PHP 5.2.5 zip 文件解压到 F:WWWSERVERphp 目录下面。安装 php 不建议使用 win32 安装程序(主要是以后安装扩展麻烦)。
    2. 在资源管理器中进入 php 的安装目录,将 php.ini-recommended 复制一份,命名为 php.ini。然后打开 php.ini。
    3. 找到:
      ;extension=php_mysql.dll

      将前面的 ; 号去掉, 改成:

      extension=php_mysql.dll

      MySQL 的扩展默认是没有打开的。将其打开。类似上面这样的脚本,是可选择的 php 扩展模块,如果需要加载,直接去掉前面的 ; 号即可。

    4. 找到:
      extension_dir = "./"

      将其改为你的 php 安装目录下 ext 子目录的绝对路径。例如我的:

      extension_dir = "F:/WWW/SERVER/PHP/ext/"

      这步很重要 。否则接下来 php 会找不到 php_mysql.dll 模块,无法装载。

    5. 在 Windows Vista 的系统设置中, 将 php 的目录, 加到 Path 环境变量中去。具体做法:

      右键点击 我的计算机 -> 属性 -> 高级系统属性 -> 环境变量 -> 系统变量 – Path -> 编辑,然后加入即可。用 ; 分隔多个目录。
  5. 配置 Apache 和 PHP

    打开 Apache 安装目录下的 conf 子目录中的 httpd.conf 文件。

    1. 找到:
      DocumentRoot "xxxxxxx"

      改成你本机的网站内容的目录。例如我的:

      DocumentRoot "F:/WWW/Web/"
    2. 找到 LoadModule,根据你的 php 安装目录,在下面空白处加上这两行:
      LoadModule php5_module "F:/WWW/SERVER/PHP/php5apache2_2.dll"
      PHPIniDir "F:/WWW/SERVER/PHP"
    3. 找到:
      DirectoryIndex index.html

      修改为:

      DirectoryIndex index.php index.html
    4. 找到:
      AddType application/x-gzip .gz .tgz

      添加这两行:

      AddType application/x-httpd-php .php
      AddType application/x-httpd-php .html
    5. 保存 httpd.conf
    6. 在你的网站目录中(例如我的是 F:/WWW/Web/),手工建立一个 index.php 的文件,内容:
      <?php
      phpinfo();
      ?>
    7. 在 dos 窗口中启动 Apache 服务
      #如果之前启动了,先将其  stop
      F:WWWSERVERapachebin> httpd -k stop
      #启动 Apahce 服务
      F:WWWSERVERapachebin> httpd -k start
      

      或者点击桌面任务栏右下角的 Apache 图标,进行操作

    8. 打开 http://localhost/index.php,即可看到测试输出结果。
  6. Windows Vista 下安装 MySQL

    MySQL 的安装比较简单,它提供了一个 win32 的安装包。下载后根据提示一路安装,在安装类型处选 Custom,指定安装目录为 F:/WWW/SERVER/mysql。

    安装完成后,会问你要不要到官网注册,跳过即可。然后会问你是否 Configure the MySQL Server now,选中并继续,然后根据提示,设定字符集,以及 root 管理员的密码即可。

    不过我在 Vista 下安装 MySQL 5.0/5.1 都无法 Configure,装成 MySQL 4.1 就好了。如果 MySQL 服务无法启动,把 my.ini 删除,就能启动服务了。

好了, 现在可以在 Vista 下使用 Apache + MySQL + php 开发 Web 程序了。

标签, , , | 日志分类:网络技术

平面三角剖分

9 评论34次阅读2008.02.23 20:33 作者:Felicia 编辑

[阅读更多]

给出平面上的一个点集,求该点集的三角剖分。

此程序是利用平面三角剖分求平面欧几里德最小生成树。可以证明,平面欧几里德最小生成树的树边一定在平面三角剖分的边中。经过 LiZhiXu 的精心简化,已经达到能在现场赛中输入的程度了

下面是代码

下载: Delaunay.cpp
#include <iostream>
#include <cmath>
using namespace std;
 
#define Oi(e) ((e)->oi)
#define Dt(e) ((e)->dt)
#define On(e) ((e)->on)
#define Op(e) ((e)->op)
#define Dn(e) ((e)->dn)
#define Dp(e) ((e)->dp)
#define Other(e, p) ((e)->oi == p ? (e)->dt : (e)->oi)
#define Next(e, p) ((e)->oi == p ? (e)->on : (e)->dn)
#define Prev(e, p) ((e)->oi == p ? (e)->op : (e)->dp)
#define V(p1, p2, u, v) (u = p2->x - p1->x, v = p2->y - p1->y)
#define C2(u1, v1, u2, v2) (u1 * v2 - v1 * u2)
#define C3(p1, p2, p3) ((p2->x - p1->x) * (p3->y - p1->y) - (p2->y - p1->y) * (p3->x - p1->x))
#define Dot(u1, v1, u2, v2) (u1 * u2 + v1 * v2)
 
#define MAXN 100001
 
struct point {
    
int x, y;
    
struct edge *in;
    
bool operator < (const point &p1) const {
        
return x < p1.x || (x == p1.x && y < p1.y);
    
}
};
 
struct edge {
    
point *oi, *dt;
    
edge *on, *op, *dn, *dp;
};
 
struct gEdge {
    
int u, v;
    
double w;
    
bool operator < (const gEdge &e1) const {return w < e1.w;}
}E[3 * MAXN], MST[MAXN];
 
int N, M;
int f[MAXN], d[MAXN];
 
void Init() {
    
for(int i = 0; i < N; ++i) f[i] = i, d[i] = 0;
}
 
int Find(int x) {
    
int i = x, t = x;
    
while(f[i] != i) i = f[i];
    
while(f[t] != i) {
        
int temp = f[t]; f[t] = i; t = temp;
    
}
    
return i;
}
 
void Make(int x, int y) {
    
x = Find(x); y = Find(y);
    
if(d[x] > d[y]) f[y] = x;
    
else {
        
f[x] = y;
        
if(d[x] == d[y]) d[y]++;
    
}
}
 
void Kruskal() {
    
double length = 0.0;
    
Init();
    
sort(E, E + M);
    
for(int i = 0, k = 0; i < M && k < N - 1; ++i) {
        
if(Find(E[i].u) != Find(E[i].v)) {
            
Make(E[i].u, E[i].v); MST[k++] = E[i]; length += E[i].w;
        
}
    
}
    
printf("%.4lfn", length);
}
 
point p[MAXN], *Q[MAXN];
edge mem[3 * MAXN], *elist[3 * MAXN];
int nfree;
 
void Alloc_memory() {
    
nfree = 3 * N;
    
edge *e = mem;
    
for(int i = 0; i < nfree; ++i) elist[i] = e++;
}
 
void Splice(edge *a, edge *b, point *v) {
    
edge *next;
    
if(Oi(a) == v) next = On(a), On(a) = b;
    
else next = Dn(a), Dn(a) = b;
    
if(Oi(next) == v) Op(next) = b;
    
else Dp(next) = b;
    
if(Oi(b) == v) On(b) = next, Op(b) = a;
    
else Dn(b) = next, Dp(b) = a;
}
 
edge *Make_edge(point *u, point *v) {
    
edge *e = elist[--nfree];
    
e->on = e->op = e->dn = e->dp = e; e->oi = u; e->dt = v;
    
if(u->in == NULL) u->in = e; if(v->in == NULL) v->in = e;
    
return e;
}
 
edge *Join(edge *a, point *u, edge *b, point *v, int side) {
    
edge *e = Make_edge(u, v);
    
if(side == 1) {
        
if(Oi(a) == u) Splice(Op(a), e, u);
        
else Splice(Dp(a), e, u);
        
Splice(b, e, v);
    
}
    
else {
        
Splice(a, e, u);
        
if(Oi(b) == v) Splice(Op(b), e, v);
        
else Splice(Dp(b), e, v);
    
}
    
return e;
}
 
void Remove(edge *e) {
    
point *u = Oi(e), *v = Dt(e);
    
if(u->in == e) u->in = e->on; if(v->in == e) v->in = e->dn;
    
if(Oi(e->on) == u) e->on->op = e->op;
    
else e->on->dp = e->op;
    
if(Oi(e->op) == u) e->op->on = e->on;
    
else e->op->dn = e->on;
    
if(Oi(e->dn) == v) e->dn->op = e->dp;
    
else e->dn->dp = e->dp;
    
if(Oi(e->dp) == v) e->dp->on = e->dn;
    
else e->dp->dn = e->dn;
    
elist[nfree++] = e;
}
 
void Make_Graph() {
    
for(int i = 0; i < N; ++i) {
        
point *u = &p[i];
        
edge *start = u->in, *e = u->in;
        
do {
            
point *v = Other(e, u);
            
if(u < v) {
                
E[M].u = u - p, E[M].v = v - p;
                
E[M++].w = hypot(u->x - v->x, u->y - v->y);
            
}
            
e = Next(e, u);
        
} while(e != start);
    
}
}
 
void Low_tangent(edge *e_l, point *o_l, edge *e_r, point *o_r, edge **l_low, point **OL, edge **r_low, point **OR) {
    
point *d_l = Other(e_l, o_l), *d_r = Other(e_r, o_r);
    
while(true) {
        
if(C3(o_l, o_r, d_l) < 0.0) {
            
e_l = Prev(e_l, d_l);
            
o_l = d_l; d_l = Other(e_l, o_l);
        
}
        
else if(C3(o_l, o_r, d_r) < 0.0) {
            
e_r = Next(e_r, d_r);
            
o_r = d_r; d_r = Other(e_r, o_r);
        
}
        
else break;
    
}
    *
OL = o_l, *OR = o_r;
    *
l_low = e_l, *r_low = e_r;
}
 
void Merge(edge *lr, point *s, edge *rl, point *u, edge **tangent) {
    
double l1, l2, l3, l4, r1, r2, r3, r4, cot_L, cot_R, u1, v1, u2, v2, N1, cot_N, P1, cot_P;
    
point *O, *D, *OR, *OL;
    
edge *B, *L, *R;
    
Low_tangent(lr, s, rl, u, &L, &OL, &R, &OR);
    *
tangent = B = Join(L, OL, R, OR, 0);
    
O = OL, D = OR;
    
do {
        
edge *El = Next(B, O), *Er = Prev(B, D), *next, *prev;
        
point *l = Other(El, O), *r = Other(Er, D);
        
V(l, O, l1, l2); V(l, D, l3, l4); V(r, O, r1, r2); V(r, D, r3, r4);
        
double cl = C2(l1, l2, l3, l4), cr = C2(r1, r2, r3, r4);
        
bool BL = cl > 0.0, BR = cr > 0.0;
        
if(!BL && !BR) break;
        
if(BL) {
            
double dl = Dot(l1, l2, l3, l4);
            
cot_L = dl / cl;
            
do {
                
next = Next(El, O);
                
V(Other(next, O), O, u1, v1); V(Other(next, O), D, u2, v2);
                
N1 = C2(u1, v1, u2, v2);
                
if(!(N1 > 0.0)) break;
                
cot_N = Dot(u1, v1, u2, v2) / N1;
                
if(cot_N > cot_L) break;
                
Remove(El);
                
El = next;
                
cot_L = cot_N;
            
} while(true);
        
}
        
if(BR) {
            
double dr = Dot(r1, r2, r3, r4);
            
cot_R = dr / cr;
            
do {
                
prev = Prev(Er, D);
                
V(Other(prev, D), O, u1, v1); V(Other(prev, D), D, u2, v2);
                
P1 = C2(u1, v1, u2, v2);
                
if(!(P1 > 0.0)) break;
                
cot_P = Dot(u1, v1, u2, v2) / P1;
                
if(cot_P > cot_R) break;
                
Remove(Er);
                
Er = prev;
                
cot_R = cot_P;
            
} while(true);
        
}
        
l = Other(El, O); r = Other(Er, D);
        
if(!BL || (BL && BR && cot_R < cot_L)) { B = Join(B, O, Er, r, 0); D = r; }
        
else { B = Join(El, l, B, D, 0); O = l; }
    
} while(true);
}
 
void Divide(int s, int t, edge **L, edge **R) {
    
edge *a, *b, *c, *ll, *lr, *rl, *rr, *tangent;
    
int n = t - s + 1;
    
if(n == 2) *L = *R = Make_edge(Q[s], Q[t]);
    
else if(n == 3) {
        
a = Make_edge(Q[s], Q[s + 1]), b = Make_edge(Q[s + 1], Q[t]);
        
Splice(a, b, Q[s + 1]);
        
double v = C3(Q[s], Q[s + 1], Q[t]);
        
if(v > 0.0) {
            
c = Join(a, Q[s], b, Q[t], 0);
            *
L = a; *R = b;
        
}
        
else if(v < 0.0) {
            
c = Join(a, Q[s], b, Q[t], 1);
            *
L = c; *R = c;
        
}
        
else { *L = a; *R = b; }
    
}
    
else if(n > 3) {
        
int split = (s + t) / 2;
        
Divide(s, split, &ll, &lr); Divide(split + 1, t, &rl, &rr);
        
Merge(lr, Q[split], rl, Q[split + 1], &tangent);
        
if(Oi(tangent) == Q[s]) ll = tangent;
        
if(Dt(tangent) == Q[t]) rr = tangent;
        *
L = ll; *R = rr;
    
}
}
 
int main() {
    
while(scanf("%d", &N) != EOF) {
        
if(N == 1) {
            
printf("0.0000n");
            
continue;
        
}
        
Alloc_memory();
        
for(int i = 0; i < N; ++i) {
            
scanf("%d %d", &p[i].x, &p[i].y);
            
p[i].in = NULL;
        
}
        
sort(p, p + N);
        
for(int i = 0; i < N; i++) Q[i] = p + i;
        
edge *L, *R;
        
Divide(0, N - 1, &L, &R);
        
M = 0;
        
Make_Graph();
        
Kruskal();
    
}
    
return 0;
}

Blog搬家过程中三大BlogWriter的使用感想

3 评论17次阅读2008.02.20 21:19 作者:Felicia 编辑

[阅读更多]

寒假的时候,想自己建一个Blog,彻底摆脱BSP的控制。虽然Blog托管给BSP有好处(比如可能发布到BSP首页带来更多的流量),但是我还是喜欢更自由的Blog管理方式。于是在53dns花了2米买了个域名,又在meyu.net花了75米买了个空间。空间是php+MySQL的,当然装了个WordPress。于是张罗着把原先cppblog的文章转移过来。

看上去不过是转移141篇文章,但是本人很懒,不想一个一个手工复制粘贴并且重新调整格式。于是baidu一下,找到几个Blog搬家软件和网站,都不怎么样,无法提供我需要的搬家服务。cppblog的数据备份下来个xml文件,在WordPress里面也无法导入,原因是格式不对。也想过写个程序转换xml格式,但是苦于不了解WordPress的导入xml结构,于是放弃了这个念头。

继续baidu……然后就发现了一个BlogWriter,叫做Zoundry。抱着试试看的态度,我装了它。一开始感觉还不错,至少能一次性把我的cppblog中的所有文章全部下载到本地。不过看看About页面,Zoundry已经在2005年停止更新了。我试用了一段时间,搬了大概20篇文章过来,感觉效率不高。而且Zoundry有个缺点,貌似对xml文件的解析有问题,cppblog中的代码框经过Zoundry解析之后,缩进全部没有了,代码都成了顶格的了,特难看。我只好手工把代码删掉,先把除了代码之外的文字搬过来。

用Zoundry一段时间之后,我就想试试看其他的BlogWriter怎么样。记得2006年我刚来WHU的时候,跟Snoopy住在一起,他那时非常推荐Windows Live Writer。我就下载下来试用。Windows Live Writer的安装非常慢,是在线安装。弄了好久之后终于安好了。设置一番,可以连上两个Blog系统。接下来我就非常郁闷了。我用Windows Live Writer查看cppblog的文章时,每次它都要从服务器下载所有文章列表,非常慢……大概每打开一篇文章(我是先搬较早写的文章),就要等好几分钟,甚至更长时间,让我受不了。和Windows Live Writer相反,Zoundry采取了聪明得多的方法,它在本地保存了一份文章列表,每次我查看文章时,它就只到服务器下载我要看的那篇。M$的白痴,真是太傻了……居然设计出这样一种算法……

无奈我放弃了Windows Live Writer。之后我又baidu到Zoundry的升级版Zoundry Raven。Zoundry Raven非常强大,我用它迅速转移了剩下的100多篇文章,感觉上操作比Zoundry要简便不少,能自动选择保留原文的日期(Zoundry要手动选日期),发布文章的时候可以在后台运行,马上能打开下一篇文章。

可恶的是,我在WordPress官网上下的latest版本居然是2.2.2的,只好重新下了个2.3.3版的,升级了一下。这下糟糕了,Zoundry Raven无法正常跟2.3.3版的Word Press交互……

于是我又回归了用浏览器在线编辑文档,就这样手工慢慢地把代码贴过去……

到现在为止,我的Blog搬家工作基本上完成了。纵观三大BlogWriter,它们各有不足之处,都不能够很好地提供我需要的服务。BlogWriter的开发者还得继续努力啊!

标签, , | 日志分类:心情日记