cf1270EE. Divide Points(构造)

Posted heyuhhh

tags:

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

传送门

题意:
给出(n,nleq 3000)个互不重合的点,现在将点分为两组,使得不同组中点的距离不等于任何两个在同一组中点的距离。
给出一个分组方案。

思路:
这是一个构造题。
将点按照坐标的奇偶分类,一共只有四类:
[ (0,0),(0,1),(1,0),(1,1) ]
会发现我们这样分组可以得到合法的方案:
[ egin{aligned} (0,0)+(1,1)&,(0,1)+(1,0)(0,0)&,(1,1) end{aligned} ]
会发现第一种,不同组之间的距离为奇数,同组的距离为偶数;而第二种,同组中的距离为((2k)^2),不同组中的距离为((2k+1)^2),因为他们在同余(4)的意义下不相等,所以也不可能出现二者相等的情况。
但现在的问题是,可能((0,0),(1,1))类的坐标不存在或者只有一个。
这里有个(trick),就是平移坐标系,将第一个点视为原点,若所有的点全为偶数,那么将坐标都除以(2)不影响最终答案,直至至少有两类坐标出现(((0,0))一直都有)。
然后类似分组就行。
想不到...真的想不到...

/*
 * Author:  heyuhhh
 * Created Time:  2020/1/31 22:16:10
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '
'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '
'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1000 + 5;
 
int n;
int x[N], y[N];
 
void run(){
    for(int i = 1; i <= n; i++) cin >> x[i] >> y[i];
    for(int i = n; i >= 1; i--) x[i] -= x[1], y[i] -= y[1];
    while(1) {
        int f = 0;
        for(int i = 1; i <= n; i++) {
            if((x[i] & 1) || (y[i] & 1)) f = 1;
        }   
        if(f) break;
        for(int i = 1; i <= n; i++) x[i] >>= 1, y[i] >>= 1;
    }
    vector <int> ans;
    for(int i = 1; i <= n; i++) {
        if(x[i] % 2 == 0 && y[i] % 2 == 0) ans.push_back(i);   
    }
    int f = 0;
    for(int i = 1; i <= n; i++) {
        if((x[i] & 1) != (y[i] & 1)) f = 1;
    }
    if(f) {
        for(int i = 1; i <= n; i++) {
            if((x[i] & 1) && (y[i] & 1)) ans.push_back(i);
        }   
    }
    cout << sz(ans) << '
';
    for(auto it : ans) cout << it << ' ';
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

以上是关于cf1270EE. Divide Points(构造)的主要内容,如果未能解决你的问题,请参考以下文章

CF1270D Strange Device

CF1270H. Number of Components

CF792C Divide by Three

CF1444B Divide and Sum(结论题)

CF1444B Divide and Sum(结论题)

Covered Points Count CF1000C 思维 前缀和 贪心