题目描述
Pb 去郊游啦!他来到一块空地打算在这里搭一个帐篷。
但是,帐篷的四个支撑点不能在落在任何位置上,而只能落在一些固定点上。现在,他找到地面上有 N 个点可以支撑帐篷。(四个支撑点必须围成一个矩形) 他想知道依次每加多一个点,搭帐篷的方法数。
输入格式
第1行:一个整数N
第2行至N+1行:每行有两个整数的x, y作为一个点的坐标。
输出格式
共N行:第i行表示当前加入第i个点后可以搭帐篷的方案数。

这题的关键在于如何判断任意四个点是矩形。
在数学上,矩形的判定有4种方式
1.有三个角是直角的四边形是矩形;
2.对角线互相平分且相等的四边形是矩形;
3.有一个角为直角的平行四边形是矩形;
4.对角线相等的平行四边形是矩形。
于是显然我们可以看出来,第一种和第三种方法肯定时候超时的
而第二种和第四种,从本质上讲,我们在是实现时是一样的
于是现在的问题是我们要如何快速判断对角线相等且平分

我们可以知道的是合法的对角线一定是这样的,对于一个矩形的两条对角线,我们可以知道他们的交叉点是相等的
而这个交叉点的横坐标是如图确定出一条对角线的两个点横坐标的和的一半,纵坐标同理
所以我们要先解决这个点,但是接着,问题出现了,只靠这一个信息是不够的。
我们目前有两个选择:
1.获取足够多的可以确定是矩形的信息
2.将三个点(矩形的两个顶点和对角线的中点)统一成一个值
显然我们肯定不愿意写第一种,因为很麻烦
所以我们可以利用第二种方式,于是我们很自然的想到了hash,为了保证答案的准确,我们只需要准备一个足够复杂和hash函数即可
而每一个hash过的数,我们用挂链法记录下来,若碰到了两个相等或是误差极小hash值,我们可以确定这四个点可以构成一个矩形,答案数加一
具体实现见代码

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = ;
const int mod = ;
const double cri = 0.0000001;
struct enkidu {
double x, y;
}a[maxn];
struct Shiki {//Ryougi
double x, y, z;
int net;
}e[mod + ];
int n, ans = ;
int ha[mod + ], len = ; inline int read() {
int x = , y = ;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') y = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + ch - '';
ch = getchar();
}
return x * y;
} inline void insert(ll kk, double xx, double yy, double zz) {
e[++len].x = xx;
e[len].y = yy;
e[len].z = zz;
e[len].net = ha[kk];
ha[kk] = len;
} inline bool check(double a, double b) {
if(abs(a - b) < cri) return ;
else return ;
} inline void hash(double x, double y, double z) {
ll k = x * y + y * z + x * z + x + y + z + mod;
if(k < ) k = -k;
k %= mod;
//cout << k << '\n';
for(int i = ha[k]; i; i = e[i].net)
if(check(x, e[i].x) && check(y, e[i].y) && check(z, e[i].z))
ans++;
insert(k, x, y, z);
} int main() {
n = read();
for(int i = ; i <= n; ++i)
a[i].x = read(), a[i].y = read();
for(int i = ; i <= n; ++i) {
double x, y, z;
for(int j = ; j < i; ++j) {
x = (a[i].x + a[j].x) / ;
y = (a[i].y + a[j].y) / ;
z = ((a[i].x - a[j].x) * x + (a[i].y - a[j].y) * y) / (a[i].x + a[j].y);
hash(x, y, z);
}
cout << ans << '\n';
}
return ;
}

目前接到反映加实测,上面那份代码好像死了....我....天知道发生了什么....

下面随便摆一份Ac的(hash函数不同

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = ;
const int mod = ;
struct node {
double x, y;
}a[maxn];
struct nn {
double x, y, z;
ll net;
}e[mod + ];
int n;
int lin[mod + ];
int tot = , ans = ;
double x, y, z; inline bool pd(double a, double b) {
if(abs(a - b) < 0.000000001) return ;
return ;
} inline void insert(double x, double y, double z, ll k) {
e[++tot].x = x;
e[tot].y = y;
e[tot].z = z;
e[tot].net = lin[k];
lin[k] = tot;
} inline void hash(double x, double y, double z) {
ll k = x * y + y * z + x * z + x + y + z + mod;
if(k < ) k = -k;
k %= mod;
// cout << 'k' << ':' << k <<'\n';
for(int i = lin[k]; i; i = e[i].net)
if(pd(e[i].x, x) && pd(e[i].y, y) && pd(e[i].z, z))
ans++;
insert(x, y, z, k);
} int main() {
// freopen("tents.in", "r", stdin);
// freopen("tents.out", "w", stdout);
cin >> n;
for(int i = ; i <= n; i++) {
cin >> a[i].x >> a[i].y;
for(int j = ; j < i; ++j) {
x = (a[i].x + a[j].x) / ;
y = (a[i].y + a[j].y) / ;
z = (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y);
hash(x, y, z);
}
cout << ans << '\n';
}
fclose(stdin);
fclose(stdout);
return ;

集训考试题tents的更多相关文章

  1. 集训考试题(CF510C Fox And Names的简化版)

    题目描述给定n个由小写字母组成的字符串,请你求出一个字母表顺序,使得这n个字符串是按照字典序升序排列的,数据保证存在合法的字母表顺序.如果存在多个解,输出字典序最小的那个. 输入格式第一行一个整数n. ...

  2. 好题Islands

    Orz yjc 吊打候选队 不好的思路是枚举森林的m块,这样DP显然会涉及n当做某一维,最多只能卷积优化一下 生成函数什么的n太大不用想 考虑m,k比较小,能不能把n变成一个系数,而不是维度 所以就是 ...

  3. [日常] NOIP前集训日记

    写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...

  4. 2017/10 冲刺NOIP集训记录:暁の水平线に胜利を刻むのです!

    前几次集训都没有记录每天的点滴……感觉缺失了很多反思的机会. 这次就从今天开始吧!不能懈怠,稳步前进! 2017/10/1 今天上午进行了集训的第一次考试…… 但是这次考试似乎是近几次我考得最渣的一次 ...

  5. 佳木斯集训Day1

    23333第一次写博客 其实在佳木斯集训之前我都已经两三个月没打代码了 在佳木斯的时候前几天真心手生,导致了前几次考试考的很差... D1的考试还是比较良心的,T1是一道大模拟,直接枚举最后几位是00 ...

  6. 「疫期集训day3」要塞

    战友们正讨论着他们曾经参加过凡尔登战役的父亲...在黎明前我们必须誓死坚守----法乌克斯要塞中弹尽粮绝的法军士兵 什么!今天又考状压和tarjan! 达成成就:连续两天复习数论和二分图 康乐康,这次 ...

  7. QDEZ集训笔记【更新中】

    这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...

  8. 2015UESTC 暑假集训总结

    day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...

  9. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

随机推荐

  1. 51nod 1819 黑白树V2(树链剖分)

    第一次写如此复杂的树链剖分, 感觉自己代码能力还是挺不错的,没有调试太久(2个小时) 最后代码量高达11K orz(大部分都是重复的线段树代码,以后可以考虑优化一下代码量) 题解: 首先就是要进行一次 ...

  2. IIS注册asp.net4.0

    1. 运行->cmd 2. cd  C:\Windows\Microsoft.NET\Framework64\v4.0.30319 3. aspnet_regiis.exe -i

  3. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

  4. 【NOIP模拟赛】Evensgn 的债务 乱搞

    biubiu~~~ 我们发现按照这道题的题意我们把一个个人的前后(欠钱,被欠钱)都缩一下,那么他对其他人没有影响,那么我们就可以依次缩完每个人,而且每个人最后的状态都是要买欠要么被欠,那么我们可以知道 ...

  5. 一些奇怪的JavaScript试题

    JavaScript有很多地方和我们熟知的C.Java等的编程习惯不同,这些不同会产生很多让人意想不到的事情.前段时间在知乎有人发了写Javascrtip试题,觉得挺好玩的,这里跟大家分享一下. 01 ...

  6. 关于session variables 和 global variables

    背景 有同学问到这样一个问题:原来的binlog格式是statement,为什么执行了 set global binlog_format='row' 和 set binlog_format='row' ...

  7. Codeforces Round #328 (Div. 2) A

    A. PawnChess time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  8. UVA10480:Sabotage(最小割+输出)

    Sabotage 题目链接:https://vjudge.net/problem/UVA-10480 Description: The regime of a small but wealthy di ...

  9. Eclipse中的Web项目自动部署到Tomcat的webapp目录下

    Eclipse中的Web项目自动部署到Tomcat   原因 很长时间没用Eclipse了,近期由于又要用它做个简单的JSP项目,又要重新学习了,虽然熟悉的很快,但记忆总是很模糊,偶尔犯错,以前很少写 ...

  10. bzoj1578 [Usaco2009 Feb]Stock Market 股票市场

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1578 [题解] 由于连续买相当于每天买,第二天卖,然后再买.所以每天最后钱尽量多一定是最优的 ...