zoukankan      html  css  js  c++  java
  • 【codeforces 527D】Clique Problem

    【题目链接】:http://codeforces.com/contest/527/problem/D

    【题意】

    一维线段上有n个点
    每个点有坐标和权值两个域分别为xi,wi;
    任意一对点(i,j)
    如果|xi-xj|>=wi+wj
    则在这两个点之间连一条边;
    让你求最大团;
    团就是任意两个点之间都有边相连;

    【题解】

    |xi-xj|>=wi+wj;
    这里的绝对值直接去掉好了;
    然后可以变形为
    xi-wi>=xj+wj
    (或者是xj-wj>=xi+wi也没差)
    总之就是xi-wi如果比另外一个点的xj+wj来得大的话;
    就能在这对点之间建立一条边;
    按照这个规则
    我们处理出每个点的
    xi-wi和xi+wi;
    记为p1域和p2域
    把所有的点按照p2域升序排一下;
    p2域相同的话,p1域随意;
    然后选取第一个点p2域作为temp;
    然后

    for (i=2;i<=n;i++)
    if (i->p1域>=temp)
    {
        temp = i->p2域;
        ans++;
    /*
        这里因为i->p1域大于等于temp,所以这个点的p1域肯定也
        大于之前的所有点,所以能和之前的所有点都建一条边,符合团的定义;
        同时因为我们把p2域升序排了,所以遇到p1域大于temp的,直接选它肯定不会影响到后面的点的选取,因为如果你后面的点能选的话,肯定不及选这个点来得优秀,因为这个点的p2域比较小啊,你选后面那个点的也是只能给答案递增1,选这个也是只能给答案递增1,显然选p2域小一点的合适啊。因为这样为你"能够选到更多的点"做了贡献
    */
    }


    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define ps push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int, int> pii;
    typedef pair<LL, LL> pll;
    
    const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
    const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
    const double pi = acos(-1.0);
    const int N = 2e5+100;
    
    struct abc
    {
        int xsw, xpw;
    };
    
    int n,temp,ans = 1;
    abc a[N];
    
    bool cmp(abc a, abc b)
    {
        return a.xpw < b.xpw;
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        rei(n);
        rep1(i, 1, n)
        {
            int x, w;
            rei(x), rei(w);
            a[i].xsw = x - w, a[i].xpw = x + w;
        }
        sort(a + 1, a + 1 + n, cmp);
        temp = a[1].xpw;
        rep1(i, 2, n)
        {
            if (a[i].xsw >= temp)
            {
                temp = a[i].xpw;
                ans++;
            }
        }
        printf("%d
    ", ans);
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
  • 相关阅读:
    数组中只出现一次的数字
    平衡二叉树
    二叉树的深度
    数字在排序数组中出现的次数
    两个链表的第一个公共结点
    数组中的逆序对
    第一个只出现一次的字符
    丑数
    新浪微博授权时出现"关注 *** 的微博"
    Bear 實驗室: 什麼是Git flow ? 如何在SourceTree使用Git flow管理開發!
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626505.html
Copyright © 2011-2022 走看看