二分专题

1.      

                                                                           Number of Triplets

                                                                                                         time limit  2 seconds

You are given n points on a plane. All points are different. Find the number of different groups of three points (A, B, C) such that point B is the middle of segment AC. The groups of three points are considered unordered, that is, if point B is the middle of segment AC, then groups (A, B, C) and (C, B, A)are considered the same.

Input

The first line contains a single integer n (3 ≤ n ≤ 3000) — the number of points. Next n lines contain the points. The i-th line contains coordinates of the i-th point: two space-separated integers xi, yi( - 1000 ≤ xi, yi ≤ 1000). It is guaranteed that all given points are different.

Output

Print the single number — the answer to the problem.

Examples

input

3
1 1
2 2
3 3
output

1

input

3
0 0
-1 0
0 1

output

0

二分查找结构体的方法 *   另外也要注意二分查找法,不用递归,直接在一个while中解决即可。也可用bool类型的数组来记录是否有这个点的情况,如果数组够开的话;

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

struct node                                 //*
{
    int x,y;
   friend bool operator < (node a,node b)   //要加friend
    {
        if(a.x==b.x)
            return a.y<b.y;
        else
            return a.x<b.x;
    }
   friend  bool operator ==(node a,node b)
    {
        return a.x==b.x&&a.y==b.y;
    }

}point[3005];
int cnt;
void judge(int l,int r)
{



    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(point[mid]==point[0])
         {
            cnt++;
            break;
         }
        else
            point[0]<point[mid]?r=mid-1:l=mid+1;
    }


}
int main()
{
    int n;
    while(cin >>n)
    {
        for(int i=1;i<=n;i++)
        {
            cin>>point[i].x>>point[i].y;
            //arr[(int)x+1000][(int)y+1000]=1;
        }

        sort(point+1,point+n+1);


        cnt=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
               point[0].x=(point[i].x+point[j].x)/2;
               point[0].y=(point[i].y+point[j].y)/2;
          if(point[0].x*2!=point[i].x+point[j].x||point[0].y*2!=point[i].y+point[j].y)continue;
               else
               {
                   judge(1,n);
               }
            }

        }
        cout <<cnt<<endl;
    }

    return 0;
}

二维矩阵二分(输入挂加二分)

                                           问题 L: Largest Allowed Area

                                                               时间限制: 1 Sec  内存限制: 128 MB

题目描述

A company is looking for land to build its headquarters. It has a lot of money and can buy as many land patches as it needs. Its goal, however, is finding the largest square region containing no forest. Unfortunately, there is no such region that is large enough for the headquarters they want to build. 
   
After negotiation with the government and the evaluation of environmental impacts, the government allows the company to purchase land with at most one forest patch. In other words, the company’s goal is now finding the largest square region containing at most one forest patch. 
 
To facilitate the search process, the company creates a map in the form of a 2D table consisting R rows and C columns. In this 2D table, each entry represents a land of patch where 0 corresponds to a non-forest patch and 1 to a forest patch. Unfortunately, the map may have up to 1,000 x 1,000 entries and it is not a good idea to manually look for the largest allowed square region. This is where your skill comes into play. Write an efficient algorithm to find such a square region. 

 

输入

The first line is a positive integer T <= 20 representing the number of test cases. For each case, the input is formatted as follows. 


Note: there is at least one non-forest patch in each test case. 

 

输出

There are T lines in the output. Each line is the number of rows in the largest allowed square region for each case. 

 

样例输入

复制样例数据
2 
10 20 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1  
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
20 10 
1 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0

样例输出

9
7

题意:求包含  <=1个 1的最大正方形

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

namespace IO
{
    template <typename T>
    inline bool read (T &ret)
    {
        char c;
        int sgn;
        if (c = getchar(), c == EOF)return false; //EOF
        while (c != '-' && (c < '0' || c > '9') )
            if((c = getchar()) == EOF) return false;
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return true;
    }

    template<typename T>
    void print(T x)
    {
        static char s[40], *s1;
        s1 = s;
        if (!x) *s1++ = '0';
        if (x < 0) putchar('-'), x = -x;
        while(x) *s1++ = (x % 10 + '0'), x /= 10;
        while(s1-- != s) putchar(*s1);
    }

    template<typename T>
    void println(T x)
    {
        print(x);
        putchar('\n');
    }
};

int max(int x, int y){
    return x > y ? x : y;
}

int min(int x, int y){
    return x < y ? x : y;
}

using namespace IO;

int sum[1005][1005];
int erfen(int x,int y,int k)
{
    int ans=0;
    int l=1,r=k,mid;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(sum[x][y]-sum[x-mid][y]-sum[x][y-mid]+sum[x-mid][y-mid]<=1)
        {
            ans=mid;
            l=mid+1;
        }
        else
            r=mid-1;
    }
    return ans;
}
int main()
{
    int t;
    read(t);
    while(t--)
    {
        memset(sum,0,sizeof(sum));
        int r,c;
        read(r);
        read(c);
        for(int i=1; i<=r; i++)
            for(int j=1; j<=c; j++)
               read(sum[i][j]);

        for(int i=1; i<=r; i++)
            for(int j=1; j<=c; j++)
                sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];

        int ans=0;
        for(int i=1; i<=r; i++)
            for(int j=1; j<=c; j++)
            {
                int k=min(i,j);
                ans=max(ans,erfen(i,j,k));
            }
        println(ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值