题目描述
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. BZOJ4584 APIO2016赛艇(动态规划+组合数学)

    如果值域不大,容易想到设f[i][j]为第i个学校选了j的方案数,枚举上一个学校是哪个选了啥即可,可以前缀和优化.于是考虑离散化,由于离散化后相同的数可能可以取不同的值,所以枚举第一个和其所选数(离散 ...

  2. 从统计学statistics的观点看概率分布

    已知数据x,希望得到未知label y,即得到映射x-->y: 几个概念: 1)p(x): data distribution 数据分布 2)p(y): prior distribution 先 ...

  3. 【BZOJ 2324】[ZJOI2011]营救皮卡丘 费用流

    本人实行诱骗拐卖(利用自然分层与实际意义),正解拼接补充(充分利用最大流限制(不浪费任何一个走出去的机会而不是不浪费任何一个已有的流)与问题转换) #include <cstdio> #i ...

  4. 【NOIP 模拟赛】改造二叉树 最长上升子序列

    biubiu~~~ 这道题我一眼就以为是线段树优化dp并且有了清晰的思路但是发现,我不会线段树区间平移,我以为只是我不会,然而根本就不行........ 正解是把序列排出来然后我们让他们减去他们的下标 ...

  5. 【BZOJ4325】NOIP2015 斗地主 搜索+贪心

    这个东西考试的时候一眼以为状压就压炸了考试又了一下午.....最后我打出来发现后几个点10min都过不去,我大概算了一下,可能是吧.......最后一脸懵逼的我去怂了正解,我们发现只要确定了顺子就可以 ...

  6. CentOS 安装 debuginfo-install

    安装debuginfo相关的包步骤如下: 1. 修改文件/etc/yum.repos.d/CentOS-Debuginfo.repo中的enabled参数,将其值修改为1 2. 使用命令: yum i ...

  7. background-color和background-image问题

    今天撸码的时候发现需要background-color和background-image 一起用,才开始考虑两个可不可以一起用  查阅多方资料才知道可以写成background:color url() ...

  8. HDU 1395

    2^x mod n = 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  9. Hadoop之计数器与自定义计数器及Combiner的使用

    1,计数器: 显示的计数器中分为四个组,分别为:File Output Format Counters.FileSystemCounters.File Input Format Counters和Ma ...

  10. HDU 2036 改革春风吹满地 (数学)

    题目链接 Problem Description " 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)" 话说部分学生心态极好,每天就知道 ...