2019校招真题编程(十二)整理房间

92 篇文章 0 订阅

题目描述

又到了周末,小易的房间乱得一团糟。
他希望将地上的杂物稍微整理下,使每团杂物看起来都紧凑一些,没有那么乱。
地上一共有n团杂物,每团杂物都包含4个物品。第i物品的坐标用(ai,bi)表示,小易每次都可以将它绕着(xi,yi)逆时针旋转90度,这将消耗他的一次移动次数。如果一团杂物的4个点构成了一个面积不为0的正方形,我们说它是紧凑的。
因为小易很懒,所以他希望你帮助他计算一下每团杂物最少需要多少步移动能使它变得紧凑。

输入:
第一行一个数n(1 <= n <= 100),表示杂物的团数。
接下来4n行,每4行表示一团杂物,每行4个数ai, bi,xi, yi, (-104 <= xi, yi, ai, bi <= 104),表示第i个物品旋转的它本身的坐标和中心点坐标。

输出:
n行,每行1个数,表示最少移动次数。

我的思路

  1. 判断四个点是否构成正方形
    1. 四条边是否相同
    2. 对角线相等
  2. 否,则分别旋转,判断是否构成正方形

假设对图片上任意点(x,y),绕一个坐标点(rx0,ry0)逆时针旋转a角度后的新的坐标设为(x0, y0),有公式:

x 0 = ( x − r x 0 ) ∗ c o s ( a ) − ( y − r y 0 ) ∗ s i n ( a ) + r x 0 x0= (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0 x0=(xrx0)cos(a)(yry0)sin(a)+rx0
y 0 = ( x − r x 0 ) ∗ s i n ( a ) + ( y − r y 0 ) ∗ c o s ( a ) + r y 0 y0= (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0 y0=(xrx0)sin(a)+(yry0)cos(a)+ry0

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

int edu_pow(const pair<int, int>&a, const pair<int, int>&b)
{
    int distance = pow(a.first-b.first, 2) + pow(a.second-b.second, 2);
    return distance;
}

bool isSquare(const pair<int, int>&a,const pair<int, int>&b,const pair<int, int>&c,const pair<int, int>&d)
{
    int ab =edu_pow(a, b), bc =edu_pow(b, c), cd=edu_pow(c, d);
    int ad=edu_pow(a, d), ac=edu_pow(a, c), bd=edu_pow(b, d);
    if(ab==0 || bc==0 || cd==0 || ad==0 || ac==0 || bd==0)return false;
    if(ab==bc && bc==cd && cd==ad && ad==ab && ac==bd) return true; //abcd
    if(ac==bc && bc==bd && bd==ad && ad==ac && ab==cd) return true;//acbd
    if(ab==bd && bd==cd && cd==ac && ac==ab && ad==bc) return true;//abdc
    return false;
}

pair<int, int> rorate(const pair<int, int>&p1, const pair<int,int>&p2, int times)
{
    int x=p1.first, y=p1.second;
    int a=p2.first, b=p2.second;//中心点
    
    while(times>0)
    {
        int tmp = x;
        x = (b - y + a);
        y = (tmp - a + b);
        times--;
    }
    return make_pair(x, y);
}

int rorateCount(vector<int> a, vector<int>b, vector<int>c, vector<int>d)
{
    int count = 16;
    pair<int, int>axy = make_pair(a[0], a[1]), ar = make_pair(a[2], a[3]);
    pair<int, int>bxy = make_pair(b[0], b[1]), br = make_pair(b[2], b[3]);
    pair<int, int>cxy = make_pair(c[0], c[1]), cr = make_pair(c[2], c[3]);
    pair<int, int>dxy = make_pair(d[0], d[1]), dr = make_pair(d[2], d[3]);
    
    for(int i=0; i<4; i++)
    {
        for(int j=0; j<4; j++)
        {
            for(int k=0; k<4; k++)
            {
                for(int l=0; l<4; l++)
                {
                    if( isSquare(rorate(axy,ar,i), rorate(bxy,br,j), rorate(cxy,cr,k), rorate(dxy, dr, l)))
                    {
                        count = min(count, i+ j + k + l);
                    }
                    
                }
            }
        }
    }
    return count == 16 ? -1 : count;// -1 无解
}


int main()
{
    int n;
    cin>>n;
    vector<vector<int>>indexs(4*n, vector<int>(4, 0));
    for(int i=0;i<4*n; i++)
    {
        cin>>indexs[i][0]>>indexs[i][1]>>indexs[i][2]>>indexs[i][3];
    }
    
    vector<int>ans(n, 0);
    
    for(int i=0; i<n; i++)
    {
        ans[i] = rorateCount(indexs[4*i], indexs[4*i+1],indexs[4*i+2],indexs[4*i+3]) ;
    }
    
    for(int i=0; i<n; i++)
        cout<<ans[i]<<endl;
}

运行时间:5ms

占用内存:396k

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值