UVA 270 Lining Up

UVA_270

    这个题目我只想到了优化常数的办法,没想到AC了,但耗时还是不容乐观的,这个题好像是有n^2logn的算法,要先进行排序再处理,但暂时还没有找到相应的详细一点的思路。

    优化常数的办法就是用一个邻接矩阵记录一下哪两个点以前已经在某条直线上被算过了,那么在枚举的时候就不用再枚举这两个点作为一条直线了。

    后来又琢磨了一下看到的那句“按极角排序”的话,恍然大悟了,实际就是把枚举的过程由枚举两个点变成枚举一个点,之后以这个点为原点,将其余所有点按和这个点连线的斜率的大小进行排序,然后去计算每条射线上点的数目(这样是不会丢解的,因为我们枚举了所有点作为原点,必然也就枚举了可能的直线的端点,而这时直线就相当于射线了),而计算的过程是可以在O(n)的时间内完成的,排序的时间是O(nlogn),枚举的基本时间是O(n),所以总的复杂度就约是O(n^2logn)。

#include<stdio.h>
#include<string.h>
#define MAXD 710
int g[MAXD][MAXD], s[MAXD], N, x[MAXD], y[MAXD], max;
char b[110];
void init()
{
N = 0;
while(gets(b) != NULL)
{
if(b[0] == '\0')
break;
sscanf(b, "%d%d", &x[N], &y[N]);
++ N;
}
}
void solve()
{
int i, j, k, p, q, top;
memset(g, -1, sizeof(g));
max = 0;
for(i = 0; i < N; i ++)
for(j = i + 1; j < N; j ++)
if(g[i][j])
{
top = 0;
for(k = 0; k < N; k ++)
if((y[j] - y[i]) * (x[k] - x[i]) == (x[j] - x[i]) * (y[k] - y[i]))
s[top ++] = k;
if(top > max)
max = top;
for(p = 0; p < top; p ++)
for(q = p + 1; q < top; q ++)
g[s[p]][s[q]] = g[s[q]][s[p]] = 0;
}
printf("%d\n", max);
}
int main()
{
int t, tt;
gets(b);
sscanf(b, "%d", &t);
gets(b);
for(tt = 0; tt < t; tt ++)
{
init();
if(tt)
printf("\n");
solve();
}
return 0;
}

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 710
int r[MAXD], N, M, x[MAXD], y[MAXD], max, C;
char b[110];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p;
int *q = (int *)_q;
int ans = (y[*p] - y[C]) * (x[*q] - x[C]) - (y[*q] - y[C]) * (x[*p] - x[C]);
if(x[*q] - x[C] < 0)
ans = -ans;
if(x[*p] - x[C] < 0)
ans = -ans;
return ans;
}
void init()
{
N = 0;
while(gets(b) != NULL)
{
if(b[0] == '\0')
break;
sscanf(b, "%d%d", &x[N], &y[N]);
++ N;
}
}
void solve()
{
int i, j, k, p, q;
max = 2;
for(i = 0; i < N; i ++)
{
M = 0;
for(j = 0; j < N; j ++)
if(x[j] != x[i])
r[M ++] = j;
if(N - M > max)
max = N - M;
C = i;
qsort(r, M, sizeof(r[0]), cmp);
for(j = 1, k = 2; j < M; j ++)
{
p = r[j - 1], q = r[j];
if((y[p] - y[i]) * (x[q] - x[i]) == (y[q] - y[i]) * (x[p] - x[i]))
++ k;
else
{
if(k > max)
max = k;
k = 2;
}
}
if(k > max)
max = k;
}
printf("%d\n", max);
}
int main()
{
int t, tt;
gets(b);
sscanf(b, "%d", &t);
gets(b);
for(tt = 0; tt < t; tt ++)
{
init();
if(tt)
printf("\n");
solve();
}
return 0;
}


你可能感兴趣的:(ini)