CF97B:Superset——题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF97B:Superset——题解相关的知识,希望对你有一定的参考价值。

http://codeforces.com/problemset/problem/97/B

题目大意:给n个点,添加一些点,使得任意两个点:

1.在同一条线上

2.以它们为顶点构成的矩形上有其他点。

输出一组可行解。

——————————————————

我发现我根本不会做英语题……看了半天题面后就去找题解了。

http://blog.csdn.net/wust_zjx/article/details/44900093

这是其他人的题解,但我总觉得这个人说的不明不白的(自行理解半个小时才明白的我深有感触)

首先题告诉我们随意一组解都可以,这给我们很大的自由空间,直接开始想暴力。

……但是我们不可以把点填满(题中有最大点数限制)

我们通过二分平面,对于mid点,每个在l-r中的其他的点与该点所在直线的投影就是我们需要添加的点(显然)。

同时为了防止我们添加重复的点我们需要用set维护一下。

Q1:为什么我们只需要在区间中的点的投影?

A1:我们知道在大区间内我们已经把所有的点投影到了mid,那么我们画图后发现我们对于右边的区间和左边的区间中的点一定满足上面的两种条件,故不需要加点。

Q2:为什么可行?

A2:(数都是约数)第一次我们添加了n个点,第二次我们添加了n/2*2个点,第三次我们添加了n/4*4个点……我们添加logn次,我们总共添加了nlogn个点大约1.2*10^5,总共也就大约1.3*10^5个点,一定超不了。

#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<set>
#include<algorithm>
#define x first  
#define y second  
using namespace std;
typedef pair<int,int>ii;
inline int read(){
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch==-;ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
ii p[10001];
set<ii>s;
void solve(int l,int r){
    if(l>=r)return;
    int mid=(l+r)>>1;
    for(int i=l;i<=r;i++){
    s.insert(ii(p[mid].x,p[i].y));
    }
    solve(l,mid);
    solve(mid+1,r);
    return;
}
int main(){
    int n=read();
    for(int i=1;i<=n;i++){
    p[i].x=read();
    p[i].y=read();
    s.insert(p[i]);
    }
    sort(p+1,p+n+1);
    solve(1,n);
    printf("%d\n",(int)s.size());
    for(set<ii>::iterator i=s.begin();i!=s.end();i++){
    printf("%d %d\n",i->x,i->y);
    }
    return 0;
}

 

以上是关于CF97B:Superset——题解的主要内容,如果未能解决你的问题,请参考以下文章

CF97B Superset

「Codeforces 97B」Superset

「Codeforces 97B」Superset

A - Superset CodeForces - 97B(人生第一个分治法,感觉,像二分啊。。)

cf 模拟

题解 CF1063B Labyrinth

(c)2006-2024 SYSTEM All Rights Reserved IT常识