集训考试题tents
题目描述
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的更多相关文章
- 集训考试题(CF510C Fox And Names的简化版)
题目描述给定n个由小写字母组成的字符串,请你求出一个字母表顺序,使得这n个字符串是按照字典序升序排列的,数据保证存在合法的字母表顺序.如果存在多个解,输出字典序最小的那个. 输入格式第一行一个整数n. ...
- 好题Islands
Orz yjc 吊打候选队 不好的思路是枚举森林的m块,这样DP显然会涉及n当做某一维,最多只能卷积优化一下 生成函数什么的n太大不用想 考虑m,k比较小,能不能把n变成一个系数,而不是维度 所以就是 ...
- [日常] NOIP前集训日记
写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...
- 2017/10 冲刺NOIP集训记录:暁の水平线に胜利を刻むのです!
前几次集训都没有记录每天的点滴……感觉缺失了很多反思的机会. 这次就从今天开始吧!不能懈怠,稳步前进! 2017/10/1 今天上午进行了集训的第一次考试…… 但是这次考试似乎是近几次我考得最渣的一次 ...
- 佳木斯集训Day1
23333第一次写博客 其实在佳木斯集训之前我都已经两三个月没打代码了 在佳木斯的时候前几天真心手生,导致了前几次考试考的很差... D1的考试还是比较良心的,T1是一道大模拟,直接枚举最后几位是00 ...
- 「疫期集训day3」要塞
战友们正讨论着他们曾经参加过凡尔登战役的父亲...在黎明前我们必须誓死坚守----法乌克斯要塞中弹尽粮绝的法军士兵 什么!今天又考状压和tarjan! 达成成就:连续两天复习数论和二分图 康乐康,这次 ...
- QDEZ集训笔记【更新中】
这是一个绝妙的比喻,如果青岛二中的台阶上每级站一只平度一中的猫,差不多站满了吧 自己的理解 [2016-12-31] [主席树] http://www.cnblogs.com/candy99/p/61 ...
- 2015UESTC 暑假集训总结
day1: 考微观经济学去了…… day2: 一开始就看了看一道题目最短的B题,拍了半小时交了上去wa了 感觉自己一定是自己想错了,于是去拍大家都过的A题,十分钟拍完交上去就A了 然后B题写了一发暴力 ...
- JS省队集训记
不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...
随机推荐
- Codeforces Round #519 by Botan Investments翻车记
A:枚举答案即可.注意答案最大可达201,因为这个wa了一发瞬间爆炸. #include<iostream> #include<cstdio> #include<cmat ...
- ZOJ 3229 Shoot the Bullet | 有源汇可行流
题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...
- loj2540 「PKUWC 2018」随机算法
pkusc 快到了--做点题涨涨 rp. 记 \(f(S,i)\) 表示 \(S\) 这个集合是决计不能选的(要么属于独立集,要么和独立集相连),或称已经考虑了的,\(i\) 表示此集合对应的最大独立 ...
- CSS3边框会动的信封
<!DOCTYPE html><html> <head> <title>酷炫的CSS3</title> <meta charset=& ...
- codevs 1078 最小生成树 kruskal
题目描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这 ...
- POJ3020:Antenna Placement(二分图匹配)
Antnna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11093 Accepted: 5459 ...
- java的多构造函数的处理方式
/** * */ package P; import java.awt.List; import java.lang.reflect.Array; import java.util.ArrayList ...
- Python之日志操作(logging)
import logging 1.自定义日志级别,日志格式,输出位置 logging.basicConfig( level=logging.DEBUG, format='%(asctime)s | ...
- Java之戳中痛点 - (3)三目运算符的两个操作数类型尽量一致
先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...
- [CVPR2017]Online Video Object Segmentation via Convolutional Trident Network
基于三端卷积网络的在线视频目标分割 针对半监督视频目标分割任务,作者采取了和MaskTrace类似的思路,以optical flow为主. 本文亮点在于: 1. 使用共享backbone,三输出的自编 ...