【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;
}
重要的是自信,一旦有了自信,人就会赢得一切。