zoukankan      html  css  js  c++  java
  • Codeforces Round #243 (Div. 1)——Sereja and Squares

    题目链接

    • 题意:
      给n个点,求能组成的正方形的个数。

      四边均平行与坐标轴

    • 大神的分析:

      经典题
      我们考虑每一种x坐标,显然仅仅有<= sqrt{N}个x坐标出现了> sqrt{N}次,我们称这些为大的,其它为小的。


      我们先考虑大的x和其它x之间的答案,先O(sqrt{N})枚举一个大的坐标,然后for其它的每一个点,这样能够依据x坐标的差算出正方形的边长,hash检查一下就能知道这个正方形是否存在。


      之后考虑小的x和小的x之间的答案,注意到我们能够对每一个横坐标直接平方for,这样仅仅有(sqrt{N})^2 + (sqrt{N})^2 + ... + (sqrt{N})^2 = N^1.5的枚举量,之后也能够hash检查。
      O(N^1.5)


    const int MAXN = 100001;
    
    vector<int> vt[MAXN];
    bool match(int ind, int val)
    {
    	if (ind >= MAXN) return false;
    	return binary_search(all(vt[ind]), val);
    }
    
    int main()
    {
    	//    freopen("in.txt", "r", stdin);
    	int n, a, b, bound;
    	while (~RI(n))
    	{
    		REP(i, MAXN) vt[i].clear();
    		bound = (int)sqrt(n * 1.0);
    
    		REP(i, n)
    		{
    			RII(a, b);
    			vt[a].push_back(b);
    		}
    		REP(i, MAXN)
    		{
    			sort(all(vt[i]));
    		}
    		LL ans = 0;
    		REP(i, MAXN)
    		{
    			if (vt[i].size() > bound)
    			{
    				FF(j, i + 1, MAXN)
    				{
    					int dis = j - i;
    					REP(k, vt[j].size())
    					{
    						int val = vt[j][k];
    						if (match(j, val + dis) && match(i, val) && match(i, val + dis))
    							ans++;
    					}
    				}
    			}
    			else
    			{
    				REP(j, vt[i].size()) FF(k, j + 1, vt[i].size())
    				{
    					int dis = vt[i][k] - vt[i][j];
    					if (match(i + dis, vt[i][k]) && match(i + dis, vt[i][j]))
    						ans++;
    				}
    			}
    		}
    		cout << ans << endl;
    	}
    	return 0;
    }
    


  • 相关阅读:
    关于“每日代码系列”以及后续计划
    每日代码系列(22)
    每日代码系列(21)
    mvcc
    父进程是1号进程产生大量的僵尸进程的解决方案
    nginx学习之路
    Zookeeper Curator 分布式锁
    jvm垃圾收集器汇总
    MySql分库分表以及相关问题
    Https交互原理
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6795527.html
Copyright © 2011-2022 走看看