zoukankan      html  css  js  c++  java
  • CodeForces 474C Captain Marmot (数学,旋转,暴力)

    题意:给定 4n * 2 个坐标,分成 n组,让你判断,点绕点的最少次数使得四个点是一个正方形的顶点。

    析:那么就一个一个的判断,n 很小,不会超时,四个点分别从不转然后转一次,转两次。。。转四次,就这样算下去,那么如何判断是不是正方形呢?这样判定就行,把每个边都求出来,然后判定,

    这里肯定有四个边是一样,另外两个是一样的,而且还不是0,因为可能重合,关键是旋转后怎么算呢?有两个公式,假设点(x, y)绕点(a, b)转 x 角度,那么旋转后的坐标为 (xx, yy),应该是,

    xx = (x - a) cos x - (y-b) sin x + a; yy = (x-a) sin x + (y-b) cos x + b;这就是转任意角度的结果。那么剩下的就很简单了,注意,如果用int 可能会溢出,用double注意精度。

    代码如下:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    const int mod = 1e9 + 7;
    const int maxn = 400 + 5;
    int a[maxn], b[maxn], x[maxn], y[maxn];
    int xx[5], yy[5];
    
    void rot(int t, int *s){//旋转
        for(int i = 0; i < 4; ++i){//四个点旋转
            xx[t+i] = x[t+i], yy[t+i] = y[t+i];
            for(int j = 0; j < s[i]; ++j){//第 i 个数旋转
                int xxx = xx[t+i];
                xx[t+i] = a[t+i] - yy[t+i] + b[t+i];
                yy[t+i] = xxx - a[t+i] + b[t+i];
            }
        }
    }
    
    bool judge(int t, int *x, int *y){
        vector<LL> v;
        for(int i = 0; i < 4; ++i)
            for(int j = 0 ; j < 4; ++j){
                if(i == j)  continue;
                LL xx = ((LL)x[t+i]-(LL)x[t+j]) * ((LL)x[t+i]-(LL)x[t+j]) + ((LL)y[t+i]-(LL)y[t+j]) * ((LL)y[t+i]-(LL)y[t+j]);//计算边长
                v.push_back(xx);//记录边长
            }
    
        sort(v.begin(), v.end());//排序
    
        int tt = 0, ii = 0;//计算数量
        for(int i = 0 ; i < 12; ++i){
            if(v[i] == v[0] && v[i])  ++tt;
            else if(v[i] == v[11] && v[i])  ++ii;
        }
        if(tt == 8 && ii == 4)  return true;
        return false;
    }
    
    int solve(int t){
        int ans = 1000;
        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(ans < i + j + k +l)  continue;//如果小于才循环
                        int s[] = {i, j, k, l};
                        rot(t, s);
                        if(judge(t, xx, yy))  ans = i + j + k + l;
                    }
    
        return ans == 1000 ? -1 : ans;
    }
    
    int main(){
        int n;
        cin >> n;
        for(int i = 1; i <= 4*n; ++i)  scanf("%d %d %d %d", &x[i], &y[i], &a[i], &b[i]);
    
        for(int i = 1; i < 4*n; i += 4)
            cout << solve(i) << endl;
    
        return 0;
    }
    
  • 相关阅读:
    vue2.0路由-适合刚接触新手简单理解
    JAVA实现DES加密实现详解
    计算机网络: IP地址,子网掩码,网段表示法,默认网关,DNS服务器详解
    vue-自定义组件传
    mybatis 乐观锁和逻辑删除
    axios 全攻略之基本介绍与使用(GET 与 POST)
    PowerDesigner使用教程
    scala slick mysql utf8mb4 支持
    spring-boot jpa mysql emoji utfmb4 异常处理
    花生壳的ddns 关键时刻又掉链子,准备迁到阿里万网
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5666598.html
Copyright © 2011-2022 走看看