CF 474C Captain Marmot[暴力枚举 || bfs状态压缩 ]

来源:互联网 发布:模拟电路实验软件 编辑:程序博客网 时间:2024/06/04 21:17

题目链接:http://codeforces.com/problemset/problem/474/C

问题的意思还是比较简单的。

说给四个点,每个点可以绕另外一个点(对于每个点被旋转的点是给定的)旋转,每次可以旋转一个点90度。问最少多少步可以使得4个点成为一个正方形(开始的时候看错题,看成矩形了。。然后悲剧的开始怀疑数据的错误)。。如果不能的话输出-1。。

由于最多只有四个点,所以,无论如何你怎样暴力也是没有问题的。。。关键是保持正确性就好。。

直接搞就好。。

我自己是用bfs来搞的。。

Code:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <queue>using namespace std;#define INT unsigned long longconst int N = 5;bool vis[N][N][N][N];struct POINT{    int x, y;    int a, b;    int cn ;    POINT() { cn = 0; }    POINT(int xx, int yy, int aa, int bb){        x = xx;        y = yy;        a = aa;        b = bb;        cn = 0;    }};struct S{    POINT p[5];    int step ;}s;int dis(POINT a, POINT b){    return (int)sqrt((double)(a.x - b.x) * (a.x - b.x) + (double)(a.y - b.y)  * (a.y - b.y));}bool f(S x){    for(int i = 0; i < 4; i ++){        for(int j = i + 1; j < 4; j ++)        if(x.p[i].x == x.p[j].x && x.p[i].y == x.p[j].y)        return false;    }    if(dis(x.p[0], x.p[1]) == dis(x.p[2], x.p[3]) && dis(x.p[0], x.p[2]) == dis(x.p[0], x.p[3]) && x.p[0].x + x.p[1].x == x.p[2].x + x.p[3].x && x.p[0].y + x.p[1].y == x.p[2].y + x.p[3].y)    return true;    if(dis(x.p[0], x.p[2]) == dis(x.p[1], x.p[3]) && dis(x.p[0], x.p[1]) == dis(x.p[0], x.p[3])&& x.p[0].x + x.p[2].x == x.p[1].x + x.p[3].x && x.p[0].y + x.p[2].y == x.p[1].y + x.p[3].y)    return true;    if(dis(x.p[0], x.p[3]) == dis(x.p[2], x.p[1]) && dis(x.p[0], x.p[2]) == dis(x.p[0], x.p[1])&& x.p[0].x + x.p[3].x == x.p[2].x + x.p[1].x && x.p[0].y + x.p[3].y == x.p[2].y + x.p[1].y)    return true;    return false;}S change(S x, int cn){    int tx = x.p[cn].x, ty = x.p[cn].y;    x.p[cn].x = x.p[cn].b - ty + x.p[cn].a;    x.p[cn].y = tx - x.p[cn].a + x.p[cn].b;    x.step ++;    x.p[cn].cn ++;    return x;}void bfs(){    memset(vis, 0, sizeof(vis));    queue<S> q;    q.push(s);    vis[0][0][0][0] = true;    while(!q.empty()){        S tmp = q.front(), tmp1;        q.pop();        if(f(tmp)){            printf("%d\n", tmp.step);            return ;        }//        puts("bingo!");        for(int i = 0; i < 4; i ++){            if(tmp.p[i].cn == 3) continue;            tmp1 = change(tmp, i);            int _0 = tmp1.p[0].cn, _1 = tmp1.p[1].cn, _2 = tmp1.p[2].cn, _3 = tmp1.p[3].cn;//            cout << _0 << ' ' << _1 << ' ' << _2 << ' ' << _3 << endl;            if(!vis[_0][_1][_2][_3]){                q.push(tmp1);                vis[_0][_1][_2][_3] = true;            }        }    }    puts("-1");    return ;}int main(){//    freopen("1.txt", "r", stdin);    int n;    scanf("%d", &n);    while(n --){        for(int i = 0; i < 4; i ++){            scanf("%d %d %d %d", &s.p[i].x, &s.p[i].y, &s.p[i].a, &s.p[i].b);            s.p[i].cn = 0;//            cout << s.p[i].x << ' ' << s.p[i].y << ' ' << s.p[i].a << ' ' << s.p[i].b << endl;        }        s.step = 0;        bfs();    }    return 0;}

中间遇到了一些小小的问题。。最主要的还是,给定任意四个点,如何判断他们能够组成矩形或者是正方形。。

还有就是一个点绕另外一个点旋转,旋转后的坐标是多少?这些也是需要马上总结的。。。


0 0
原创粉丝点击