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

/*

分治法,第一次做不是很懂,借鉴了神犇代码,但实操之后感觉像二分,,可能做得少了或者就是。。。。

*/

题目大意:

一个集合里有若干点,要求你添加某些点后保证这个集合里的任意两点满足以下三个条件中至少一个:

1.在一个水平线上 2.在一个竖直线上 3.两点组成的矩形之间有点.

解题思路:

神犇所讲,将点排序,在中间点处建一条竖直线,令其余点在其上投影,二分。

ps:不是很明白错误是什么,,结构体里重载<运算符可以,但是写个cmp函数就报错,不是很懂,贴上错误代码,如果神犇们知道什么错误,请评论告知,多谢;

错误代码

#include<iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <cstdio>
#include <iterator>
#include <sstream>
#include <cmath>
#include <deque>
using namespace std;

struct node
{
    int x;
    int y;
//    bool operator <(const node b)const
//    {
//        if(x==b.x) return y<b.y;
//        else return x<b.x;
//    }
};
int n;
node p1[10050];
set<node > p;
bool cmp(const node a,const node b)
{
    return a.x<b.x;
}
void dfs(int l,int h)
{
    if (l==h) return ;
    int mid;
    mid=(l+h)/2;
    for (int i=l; i<=h; i++)
    {
        node c;
        c.x=p1[mid].x;
        c.y=p1[i].y;
        p.insert(c);
    }
    dfs(l,mid);
    dfs(mid+1,h);
}
int main()
{
    cin>>n;
    for (int i=0; i<n; i++)
    {
        cin>>p1[i].x>>p1[i].y;
        p.insert(p1[i]);
    }
    sort(p1,p1+n,cmp);
    dfs(0,n-1);
    cout<<p.size()<<endl;
    set<node >::iterator it;
    for (it=p.begin(); it!=p.end(); it++)
    {
        cout<<(*it).x<<" "<<(*it).y<<endl;
    }
}

AC代码:

#include<iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <cstdio>
#include <iterator>
#include <sstream>
#include <cmath>
#include <deque>
using namespace std;

struct node
{
    int x;
    int y;
    bool operator <(const node b)const
    {
        if(x==b.x) return y<b.y;
        else return x<b.x;
    }
};
int n;
node p1[10050];
set<node > p;
bool cmp(const node a,const node b)
{
    return a.x<b.x;
}
void dfs(int l,int h)
{
    if (l==h) return ;
    int mid;
    mid=(l+h)/2;
    for (int i=l; i<=h; i++)
    {
        node c;
        c.x=p1[mid].x;
        c.y=p1[i].y;
        p.insert(c);
    }
    dfs(l,mid);
    dfs(mid+1,h);
}
int main()
{
    cin>>n;
    for (int i=0; i<n; i++)
    {
        cin>>p1[i].x>>p1[i].y;
        p.insert(p1[i]);
    }
    sort(p1,p1+n);
    dfs(0,n-1);
    cout<<p.size()<<endl;
    set<node >::iterator it;
    for (it=p.begin(); it!=p.end(); it++)
    {
        cout<<(*it).x<<" "<<(*it).y<<endl;
    }
}

时间: 2024-10-20 08:58:44

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

算法导论第2章 分治法与归并排序, 二分查找法

分治策略:将原问题划分成n个规模较小而结构与原问题相似的子问题,然后递归地解决这些子问题,最后再合并其结果,就可以得到原问题的解. 它需要三个步骤: 分解:将原问题分解成一系列的子问题. 解决:递归地解决各个子问题.若子问题足够小,则直接求解. 合并:将子问题的结果合并成原问题的解. 通过分治策略和分治步骤,可以简单地默出归并算法. 分解:将n个元素分成各自包含n/2个元素的子序列 解决:用归并排序法递归地对两个子序列进行排序. 合并:合并两个以排序的子序列,得到排序结果: void merge

Codeforces 448C Painting Fence(分治法)

题目链接:http://codeforces.com/contest/448/problem/C 题目大意:n个1* a [ i ] 的木板,把他们立起来,变成每个木板宽为1长为 a [ i ] 的栅栏,现在要给栅栏刷漆,刷子宽1,刷子可以刷任意长,每次只能横着刷或者竖着刷,问最少需要刷几次?解题思路:参考了这里(https://blog.csdn.net/qq_24451605/article/details/48492573)首先我们能够想到,如果横着刷,为了得到最优解,当前刷的位置的下面也

李新海:父母是人生第一批培训师

每一个人,从生下来那一刻起,就拥有父母,而且是唯一的父母,不能选择,不能更换. 但是全天下的父母,只要是生下了自己的孩子,就会全身心的去爱这个孩子,去付出所有. 有这么一个故事,貌似经典,但是我认为是纯扯蛋,故事讲一名父亲,为了让自己的孩子锻炼能力,这个能力包括信任的能力,怀疑的能力,甚至还有胆量,就让孩子在房顶上跳下来,说父亲会接住你,会抱住你的.说到这,可能各位读者已经猜到了,我说的是哪个故事. 我个人认为,就中国而言,父亲的爱,母亲的爱都是伟大的,都是给予,就算是想锻炼孩子的能力,也不会让

人生第一个上线项目总结

此时,项目公测第一天,项目组集体坐在公司值班,等待着用户反馈,鉴于之前已经做过为期半个月的内测,于是,公测的第一天晚上似乎不是多么紧张. 毕业后,就进入现在公司,开始了现在项目.历时一年,很快.快结束的现在,总觉得自己应该总结下这一年发生的事情,于是,便记在这里,供自己"回眸".从程序员的角度看问题,更多. 使用技术:服务器,Linux + Java:客户端,Unity3D(主要NGUI). 项目框架: 服务器 客户端 1.登录服务器. 2.主要服务器M. 3.服务器G. 4.服务器D

pku3090 Visible Lattice Points:人生第一个欧拉函数

这是一道很有纪念价值的题目! Visible Lattice Points Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5812   Accepted: 3434 Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin

Snail—1-9这9个数字划分成三个3位数,第一个分别是第二、三个的2倍,3倍

//1-9这9个数字划分成三个3位数,第一个分别是第二.三个的2倍,3倍 void myGetThreeNum(){ int j,k; int <span style="font-family: Arial, Helvetica, sans-serif;">arr</span><span style="font-family: Arial, Helvetica, sans-serif;">[10],sum ;</span&g

专题:分治法

分治法(Divide and Conquer) 作为五大算法之一的分治法,可算是最早接触的一种算法.分治法,与其说是一种算法,不如将其称为策略来的更贴切一些.算法的思想就是将大问题分成小问题,并解决小问题之后合并起来生成大问题的解. 分治法的精髓: 分--将问题分解为规模更小的子问题: 治--将这些规模更小的子问题逐个击破: 合--将已解决的子问题合并,最终得出“母”问题的解: 分治法的作用,自然是让程序更加快速地处理问题.比如一个n的问题分解成两个n/2的问题,并由两个人来完成,效率就会快一些

分治法(一)

这篇文章将讨论: 1) 分治策略的思想和理论 2) 几个分治策略的例子:合并排序,快速排序,折半查找,二叉遍历树及其相关特性. 说明:这几个例子在前面都写过了,这里又拿出来,从算法设计的策略的角度把它们放在一起来比较,看看分治是如何实现滴.由于内容太多,我将再花一篇文章来写4个之前没有写过的分治算法:1,大整数乘法   2,矩阵乘法的分治策略   3,最近点对  4,凸包问题,请见下一篇. 好了,切入正题. --------------------------------------------

算法实验:分治法合并排序(C++)

这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来. 我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别.但是下面的报告是我放到vs里面测试过的,可以直接用,不影响. 第一部分:(解析) 题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组. 题目分析: 需要随机产生一个整数数组: 采用的算法是合并排序,也就是用归并排序: 输出排序后的数组. 随机产生一个整数数组:这个问题首先想到的是用rand()函