Squares-暴力枚举或者是用二分优化

B - Squares

Time Limit:3500MS     Memory Limit:65536KB     64bit IO Format:%I64d
& %I64u

Submit Status Practice POJ
2002

Description

A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however,
as a regular octagon also has this property.

So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x
and y coordinates.

Input

The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow. Each of the next n lines specify the x and y coordinates (two integers) of each point. You may assume that the
points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.

Output

For each test case, print on a line the number of squares one can form from the given stars.

Sample Input

4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0

Sample Output

1
6
1

先提供暴力枚举,二分求解,代码一出,便会上传

/*
Author: 2486
Memory: 24256 KB		Time: 375 MS
Language: C++		Result: Accepted
*/
//此题目暴力暴力枚举
//通过已经确定好的两点,算出剩下的两点
//(有两种情况)
//一个在上面,一个下面
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=20000+5;
struct point{
    int x,y;
}ps[1005];
int n,ans;
bool vis[maxn<<1][maxn<<1];
int main(){
while(~scanf("%d",&n),n){
    ans=0;
    for(int i=0;i<n;i++){
        scanf("%d%d",&ps[i].x,&ps[i].y);
        ps[i].x+=20000,ps[i].y+=20000;//在数组里面可以存储负数
        vis[ps[i].x][ps[i].y]=true;//标记着这个点存在
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<i;j++){
            if(i==j)continue;//分别代表着上下两种不同的正方形
            int nx1=ps[i].x+ps[i].y-ps[j].y;
            int ny1=ps[i].y+ps[j].x-ps[i].x;
            int nx2=ps[j].x+ps[i].y-ps[j].y;
            int ny2=ps[j].y+ps[j].x-ps[i].x;
            if(vis[nx1][ny1]&&vis[nx2][ny2])ans++;
            nx1=ps[i].x-(ps[i].y-ps[j].y);
            ny1=ps[i].y-(ps[j].x-ps[i].x);
            nx2=ps[j].x-(ps[i].y-ps[j].y);
            ny2=ps[j].y-(ps[j].x-ps[i].x);
            if(vis[nx1][ny1]&&vis[nx2][ny2])ans++;
        }
    }
    for(int i=0;i<n;i++){
        vis[ps[i].x][ps[i].y]=false;//必须要进行清零,不能用memset,因为数组有点大
    }
    printf("%d\n",ans/4);
}
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 11:11:44

Squares-暴力枚举或者是用二分优化的相关文章

uva 565 - Pizza Anyone?(暴力枚举 + 二进制)

题目:uva 565 - Pizza Anyone?(暴力枚举 + 二进制) 题目大意:题目是说有一个人要帮他的朋友们定批萨,然后每个朋友都有自己的口味要求,问能不能定一个批萨然后满足每个朋友的至少一个要求. 能就输出所定批萨里面加的东西,,输出要求按字典序: 不能就输出:No pizza can satisfy these requests. 解题思路:这题里面有16种材料,每种材料只有取与不取的可能,这样就有 2^16 种( 0 - 2^16 - 1),枚举出每种情况然后在分别看是否能满足每

HDU 1081 To The Max 暴力模拟O(n^4) dp优化O(n^3)

原题: http://acm.hdu.edu.cn/showproblem.php?pid=1081 题目大意: 求给定边长的正方形选一个矩形,使它包含的所有元素的值最大. 大家都知道(a+b)^2的展开式,这里的优化就是用了这个原理来做的优化,我们的dp值是我们前i行j列的矩形区域的值. 任意矩形区域的值通过该展开式也能求解,所以我们可以暴力枚举每种以左上角(k,l)到右下角(i,j)的情况. 对于这个题边长是100,4层循环是10^8,因为循环并跑不了这么多,刚好也能卡过去. 代码如下: #

HDU 1025:Constructing Roads In JGShining&#39;s Kingdom(LIS+二分优化)

http://acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which are located in two parallel lines.Half of these cities are r

hdu 4932 Miaomiao&#39;s Geometry 暴力枚举

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4932 Miaomiao's Geometry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 694    Accepted Submission(s): 180 Problem Description There are N point

暴力枚举篇

Q1(uva 725): 给出一个整数n,找到所有的0~9的排列,是的前五个数组成的整数能够整除后五个数组成的整数. 分析:很典型的基本暴力枚举法,暴力求解往往伴随优化.这道题目的优化点在于枚举后五位得到10x9x8x7x6种情况,然后基于这些情况和等式关系,然后得到前面的整数,然后只需判断一下是否满足每个数字只出现了一次即可,由于题目是要求从小到大输出,这里枚举的时候控制一下从小到大枚举即可. 参考代码如下: #include<cstdio> #include<cstring>

CODE FESTIVAL 2017 qual A--B-fLIP(换种想法,暴力枚举)

个人心得:开始拿着题目还是有点懵逼的,以前做过相同的,不过那是按一个位置行列全都反之,当时也是没有深究.现在在打比赛不得不 重新构思,后面一想把所有的状态都找出来,因为每次确定了已经按下的行和列后,按不同的操作所加的数都是一样的,于是就想到了用set 暴力枚举,从1-n个分别行列按钮,然后再枚举不同操作即确定行时再对列进行操作,每次操作放入set就可以了. 题目: Problem Statement We have a grid with N rows and M columns of squa

hdu5616 暴力枚举

2017-08-25 20:08:54 writer:pprp 题目简述: ? HDU 5616? n个砝码,可以放在天平左右两侧或不放? m次询问,每次询问是否可以测出给定重量? 1 ≤ n ≤ 20? 1 ≤ m ≤ 100 这道题采用枚举的思路的话实现起来还是有点困难的, 要实现的功能是对每个砝码进行处理,加到左边, 加到右边,或者是不加 看了大神的代码,感觉很巧妙, 设置了两个标记数组 vis1[2005], vis2[2005] 一个vis1用来记录当前已经可以实现的重量 另一个vis

hdu4282A very hard mathematic problem 暴力枚举

//给出k //找x,y,z使得x^z+y^z+x*y*z = k //x,y,z都为正整数x<y,z>1问有多少种方法 //当z = 2时,可以看到左边是一个完全平方 //而当z>=3时,可以暴力枚举x,y //由于k<2^31所以x<2^(31/3)枚举复杂度可以过 #include<cstdio> #include<cstring> #include<iostream> #include<cmath> using name

hdu 5247 找连续数【暴力枚举】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5247 分析:这道题是2015百度之星初赛1的2题,当时没看这道题 是队友看的,比完以后也做了一下,思路大体都是一样的,就是 暴力枚举,因为k<=1000,那么我们可以每一点x为起点跑[x,x+999] 这段区间,把每得到一段连续的子区间[x,?],则num[len]++(len=size([x,?])); 这样就可以了,最后num数组里就是对应的答案 献上代码: #include<stdio.h&