【cf1270E】E. Divide Points(构造)

传送门

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

思路:
这是一个构造题。
将点按照坐标的奇偶分类,一共只有四类:

\[(0,0),(0,1),(1,0),(1,1) \]

会发现我们这样分组可以得到合法的方案:

\[\begin{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 << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
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) << '\n';
    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;
}
posted @ 2020-01-31 23:34  heyuhhh  阅读(360)  评论(0编辑  收藏  举报