Codeforces 474C Captain Marmot 给定4个点和各自旋转中心 问旋转成正方形的次数

题目链接:点击打开链接

题意:

给定T表示case数

下面4行是一个case

每行2个点,u v

每次u可以绕着v逆时针转90°

问最少操作多少次使得4个u构成一个正方形。

思路:

枚举判可行

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
int hah,ijj;
int haifei;
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
template <class T>
inline void pt(T x) {
    if (x <0) {
        putchar('-');
        x = -x;
    }
    if(x>9) pt(x/10);
    putchar(x%10+'0');
}
///////////////////////
const double eps = 1e-8;
const double pi = acos(-1.0);
struct node {
    double x, y;
};
bool dcmp(double i, double j) {
    return fabs(i - j) <= eps;
}
bool eq(const node& i, const node& j) {
    return dcmp(i.x, j.x) && dcmp(i.y, j.y);
}
/*
x0= (x - rx0)*cos(a) - (y - ry0)*sin(a) + rx0 ;
y0= (x - rx0)*sin(a) + (y - ry0)*cos(a) + ry0 ;
*/
node turn(const node& i, const node& j, double a) {
    node re;
    re.x= (i.x - j.x)*cos(a) - (i.y - j.y)*sin(a) + j.x;
    re.y= (i.x - j.x)*sin(a) + (i.y - j.y)*cos(a) + j.y;
    return re;
}
bool cc(const node& i, const node& j) {
    if (!dcmp(i.x, j.x))
        return i.x < j.x;
    else
        return i.y < j.y;
}
double sqr(double x) {
    return x * x;
}
double D(node i, node j) {
    return sqr(i.x-j.x) + sqr(i.y-j.y);
}
double dis[20];
int idx;
bool ok(node i, node j, node k, node z) {
    node ar[4];
    ar[0]=i; ar[1]=j; ar[2]=k; ar[3]=z;
    idx = 0;
    for (int i = 0; i < 4; ++i)
        for (int j = i + 1; j < 4; ++j)
            dis[idx++]=D(ar[i],ar[j]);
    sort(dis, dis +idx);
    if (dcmp(dis[0], dis[3]) && !dcmp(dis[0], 0) && dcmp(dis[4], dis[5]) && dcmp(dis[0] * 2, dis[4])) {
        return true;
    } else
        return false;
}
int main() {
    node a[10], b[10];
    int T;
    rd(T);
    while (T -- > 0) {
        for (int i = 0; i < 4; ++i)
            scanf("%lf%lf%lf%lf", &a[i].x, &a[i].y, &b[i].x, &b[i].y);
        int ans = 100;
        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 (ok(turn(a[0], b[0], i*pi/2),turn(a[1], b[1], j*pi/2),
                   turn(a[2], b[2], k*pi/2),turn(a[3], b[3], l*pi/2))) {
                        ans = min(i+j+k+l, ans);
                   }

        if (ans == 100)
            ans = -1;
        pt(ans);
        putchar('\n');
    }
    return 0;
}
时间: 2024-08-26 13:44:43

Codeforces 474C Captain Marmot 给定4个点和各自旋转中心 问旋转成正方形的次数的相关文章

Captain Marmot(Codeforces Round #271 div2) C

Captain Marmot Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description Captain Marmot wants to prepare a huge and important battle against his enemy, Captain Snake. For this battle he has n regiments, e

给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1(ccf真题)

ccf认证考试2014年9月第一题 问题描述 给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1. 输入格式 输入的第一行包含一个整数n,表示给定整数的个数. 第二行包含所给定的n个整数. 输出格式 输出一个整数,表示值正好相差1的数对的个数. 样例输入 6 10 2 6 3 7 8 样例输出 3 样例说明 值正好相差1的数对包括(2, 3), (6, 7), (7, 8). 评测用例规模与约定 1<=n<=1000,给定的整数为不超过10000的非负整数. #include<

Codeforces 704D Captain America

题意:平面上有n个点,每个点必须涂成红色和蓝色中的一种,花费各为r和b(对所有的点花费都一样).m条限制,每条限制形如"y=b这条直线上两种颜色的点的数目之差的绝对值不能超过c"或" x=b这条直线上两种颜色的点的数目之差的绝对值不能超过c",点数和限制数10^5,坐标范围10^9. 首先看到坐标范围很大先离散化,然后变成100000*100000的网格图每行每列的限制.那么转化成二分图,原先的每个点转换成边.因为每一行每一列的总点数是已知的,"两种颜色的

Codeforces 509F Progress Monitoring 给定dfs序求树的同构数 区间dp

题目链接:点击打开链接 ==说同构数有点不对..反正就是这个意思,对于某个点的所有儿子,先访问标号小的,再访问标号大的. dp[l][r]表示 区间[l,r] 构成一棵树的方法数. 对于一个区间[l, r] 构成一棵树,则点l一定是根,然后枚举2个区间相乘即可 dp[l][r] = dp[l+1][i] * dp[i+1][r] ( i = [l+1, r] ) 当然 a[i+1] > a[l+1] ,这样才会满足题目中的暴力代码. import java.io.PrintWriter; imp

从给定的流中读取所有的数据转成字符串

public static String readStream(InputStream is){        try {            byte[] bs = new byte[1024] ;            int b = 0 ;            ByteArrayOutputStream baos = new ByteArrayOutputStream() ;            while((b=is.read(bs))!=-1){                b

codeforces 397B On Corruption and Numbers-yy-(求区间内的整数能否凑成某一整数)

题意:求一段连续的整数能否凑成某一个整数n.区间内的整数使用次数不限 分析:这题的题面的硬币凑钱,所以我刚开始以为是dp,无限背包,但是发现不是背包问题,但我还是认为是个dp,于是写了一个转移方程,似乎是对的,准备写代码的时候才发现用dp的话,数组根本不可能开那么大 10^9,所以我确定不是dp,根据经验觉得应该是个yy题,于是开始手动找规律,发现:只要n在区间 k[l,r]里面,就能用区间内的整数凑成n,换句话说就是能找到一个合法的k即可,即:n/r <= n/l ,注意一点是:当n%r==0

hdu 1806 Frequent values(给定一个非降序数组,求任意区间内出现次数最多的数的次数)

1.题目解析可见<训练指南>P198 2代码: #include<cstdio> #include<cstring> #include<cmath> #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define N 100005 #define INF 1<<30 using namespace std; int a[N]; int valu

给定一个字符串,打印输出有重复的字符和重复的次数,并且按照重复的次数升序输出

最近在面试,好多的面试题,笔试题,有的笔试题搜百度搜不到点子上的 这个刚开始看着很简单,后面说要排序,想起了用Collections里面自定义的比较器 代码: public class StringDemo { public static void main(String[] args) { String str = "asdzxasdqweasdzs"; char[] chars = str.toCharArray(); Map<Character, Integer> m

Codeforces 453C Little Pony and Summer Sun Celebration(构造)

题目链接:Codeforces 453 Little Pony and Summer Sun Celebration 题目大意:n个节点,m条边,然后m行给定边,最后一行表示每个节点需要进过的次数为奇数次还是偶数次. 解题思路:构造,任意从一个奇数点开始(统一森林的处理),然后每次向下遍历没有经过的节点,并且回溯,每次回溯都要判断一下刚才走过的点满不满足条件,不满足的话就再走一次.最后对于根节点,最后一次回溯要不要走根据当前走过的次数决定. #include <cstdio> #include