题目描述
又到了周末,小易的房间乱得一团糟。
他希望将地上的杂物稍微整理下,使每团杂物看起来都紧凑一些,没有那么乱。
地上一共有n团杂物,每团杂物都包含4个物品。第i物品的坐标用(ai,bi)表示,小易每次都可以将它绕着(xi,yi)逆时针旋转90^ \circ90∘,这将消耗他的一次移动次数。如果一团杂物的4个点构成了一个面积不为0的正方形,我们说它是紧凑的。
因为小易很懒,所以他希望你帮助他计算一下每团杂物最少需要多少步移动能使它变得紧凑。
输入描述:
第一行一个数n(1 <= n <= 100),表示杂物的团数。 接下来4n行,每4行表示一团杂物,每行4个数ai, bi,xi, yi, (-104 <= xi, yi, ai, bi <= 104),表示第i个物品旋转的它本身的坐标和中心点坐标。
输出描述:
n行,每行1个数,表示最少移动次数。
示例1
输入
4 1 1 0 0 -1 1 0 0 -1 1 0 0 1 -1 0 0 1 1 0 0 -2 1 0 0 -1 1 0 0 1 -1 0 0 1 1 0 0 -1 1 0 0 -1 1 0 0 -1 1 0 0 2 2 0 1 -1 0 0 -2 3 0 0 -2 -1 1 -2 0
输出
1 -1 3 3
说明
对于第一团杂物,我们可以旋转第二个或者第三个物品1次。
参考代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <bitset>
#include <unordered_map>
#include <stack>
#include <queue>
#include <deque>
#include <limits.h>
#include <cstdio>
using namespace std;
struct Item{
int a, b, x, y, state;
Item(){
state = 0;
}
void crot(){
state = (state + 1) % 4;
int dx = a-x, dy = b-y;
a = x - dy;
b = y + dx;
}
void input(){
cin>>a>>b>>x>>y;
state = 0;
}
bool operator ==(const Item &item2){
return a==item2.a && b==item2.b;
}
Item operator +(const Item &it2){
Item res;
res.a = a + it2.a;
res.b = b + it2.b;
return res;
}
Item operator -(const Item &it2){
Item res;
res.a = a - it2.a;
res.b = b - it2.b;
return res;
}
static bool ortho(const Item &it1, const Item &it2){
if(it1.a==0 && it1.b== 0) return 0;
if(it2.a==0 && it2.b == 0) return 0;
return it1.a * it2.a + it1.b * it2.b == 0;
}
};
struct Pack{
vector<Item> itemList;
vector<Item*> itp;
int step;
Pack(){
itemList = vector<Item>(4);
itp = vector<Item*>(4, nullptr);
for(int i=0; i<4; ++i) itp[i] = &itemList[i];
step = INT_MAX;
}
void input(){
for(int i=0; i<4;++i)
itemList[i].input();
step = INT_MAX;
}
bool isSqaure(){
for(int i=1; i<4; ++i){
if(i!=1) swap(itp[i], itp[1]);
if(*itp[0]==*itp[1] || *itp[2]==*itp[3]) return 0;
if(!(*itp[0] + *itp[1] == *itp[2] + *itp[3])) continue;
if(!Item::ortho(*itp[0]- *itp[1], *itp[2] - *itp[3])) continue;
if(Item::ortho(*itp[0]- *itp[2], *itp[0] - *itp[3])) return 1;
}
return 0;
}
void trySqaure(int rot_idx){
for(int i=0; i<4; ++i){
if(rot_idx == 0 && isSqaure()){
int tmp_step = 0;
for(int j=0; j<4; ++j) tmp_step += itemList[j].state;
if(step > tmp_step) step = tmp_step;
}
if(rot_idx > 0) trySqaure(rot_idx - 1);
itemList[rot_idx].crot();
}
}
};
int main()
{
int n;
cin>>n;
Pack eRoom;
for(int i=0; i<n; ++i){
eRoom.input();
eRoom.trySqaure(3);
cout<<(eRoom.step > 16 ? -1: eRoom.step)<<endl;
}
}