题解 P3061 【[USACO12DEC]疯狂的栅栏Crazy Fences】
这道题的思想是首先我们找到所有的栅栏围成的空间,然后求每一只奶牛在哪几个栅栏空间之中,最后比较他们在的所有栅栏空间-----如果奶牛a和b同时在空间c,d和e内,那么他们一定在同一群中。
测试围栏的方法:对于每个栅栏,如果没有被查过,就将其放入队列。然后根据这个数把所有有相同点的栅栏放入队列并将visited设成true。
测试每一只牛所在的空间的方法:对于牛B和栅栏组C,如果从B往下走碰到了奇数次栅栏,那么B一定在栅栏C的空间内。(第一次发题解实在不知道怎么发图请见谅)
测试牛是否碰到栅栏组中某一栅栏的方法:对于牛B和栅栏组C中的栅栏D,如果牛B的x坐标在栅栏D的坐标之间,且牛B的Y值大于栅栏D在牛B的x坐标这个点上的时候的Y值,那么牛B一定在栅栏D之上
测试栅栏D在牛B的x坐标的Y值:对于栅栏D,斜率等于(y2-y1)/(x2-x1),在x时的坐标为 【斜率(牛B的x值-栅栏D的第一个点的x值)+栅栏D的第一个点的y值】,也就是说: cowy>=slope(cowx-x1)+y1
求两头牛是否在同一族群:现在我们有了每一头牛所在的族群(我将它放在vec里面)。求两头牛是否在同一族群的方法是如果两头牛所在的族群的数量和编号都相同,那么这两头牛在同一族群内 # 上代码 # *****注:本蒟蒻非常反感抄袭。因为这些抄袭者是完全一字不改的抄下来,这个是在我看来不可行的。所以我特地在中间抽掉了一行(非常简单的一行)。我相信想做这题的人对于补全这行不会有问题。对于造成的不便,敬请谅解 #
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <math.h>
using namespace std;
bool visited[1001];
bool vis[1001];
pair< pair<int,int>, pair<int,int> > pos[1001]; //所有fence的起始点和结束点
pair<int,int> cows[1001];//奶牛的地点
bool check(pair< pair<int,int>, pair<int,int> > fir, pair< pair<int,int>, pair<int,int> > sec){
return ((fir.first.first == sec.first.first && fir.first.second == sec.first.second) ||
(fir.second.first == sec.first.first && fir.second.second == sec.first.second)||
(fir.first.first == sec.second.first && fir.first.second == sec.second.second) ||
(fir.second.first == sec.second.first && fir.second.second == sec.second.second));
}//测试两个fence有没有共同点
int main(){
vector<pair< pair<int,int>, pair<int,int> > > vec[1000];//记录有几个群
int a,b; cin >> a >> b;
for (int i=0;i<a;i++) cin >> pos[i].first.first >> pos[i].first.second >> pos[i].second.first >> pos[i].second.second;
for (int i=0;i<b;i++)cin >> cows[i].first >> cows[i].second;
int zz = 0;
queue<int> q;
//visited找没有经过的地点放进队列
//如果遇到没有经过并且有相同点的地方就放入队列,并将visited改成true
for (int i=0;i<a;i++){//测试每个点
if (!visited[i]){
visited[i] = true;
vec[zz].push_back(pos[i]);
q.push(i);
while(!q.empty()){//当队列中有东西
pair< pair<int,int>, pair<int,int> > temp1 = pos[q.front()];
for (int j=0;j<a;j++){
pair< pair<int,int>, pair<int,int> > temp2 = pos[j];
if (!visited[j]){
if (check(temp1,temp2)){//测试是否有共同点
q.push(j);
visited[j] = true;
vec[zz].push_back(pos[j]);
}
}
}
//这里我拿掉了一行程序(反抄袭请谅解)
//如果想填请认真看while里面缺什么。我相信会做这题的人都可以写的出来这行
}
zz++;//群数+1
}
}
vector<int> myvec[1001];
for (int i=0;i<b;i++){
for (int j=0;j<zz;j++){
int edge = 0; //设置碰到的边缘的数量为0
for (int k=0;k<vec[j].size();k++){
double x1 = vec[j][k].first.first;
double y1 = vec[j][k].first.second;
double x2 = vec[j][k].second.first;
double y2 = vec[j][k].second.second;
//这四行是为了找栅栏的起始点和终点
double cowx = cows[i].first;
double cowy = cows[i].second;
//奶牛的位置
double slope = (y2-y1) / (x2-x1);//斜率
bool cond1 = x1<=cowx && cowx<x2;
bool cond2 = x2<=cowx && cowx<x1;
//测试奶牛位置是否在两个栅栏的中间
bool above1 = (cowy >= slope * (cowx-x1) + y1); //测试奶牛是否在栅栏之上
if ((cond1^cond2) && above1) edge++;//如果奶牛位置在两栅栏之间,并且在栅栏之上,证明奶牛会碰到这个栅栏
}
if (edge % 2 !=0){
myvec[i].push_back(j);//如果是奇数,说明奶牛在这个栅栏内
}
}
}
int ans = 1;//最小可能每只牛都是独立的
for (int i=0;i<b;i++){//每只牛测试
int num = 1;
if (vis[i]) continue;
vis[i] = true;
for (int j=i;j<b;j++){
if (myvec[i].size() == myvec[j].size() && i!=j &&!vis[j]){
bool n = true;
for (int k=0;k<myvec[i].size();k++) if (myvec[i][k]!=myvec[j][k]) n = false;
if (n){
num++;//如果两个奶牛在的族群数量相同,那么他们在同一族群内
vis[j]=true;
}
}
}
ans = max(ans,num);//最大奶牛数
}
cout << ans;
}
题解 P3061 【[USACO12DEC]疯狂的栅栏Crazy Fences】的更多相关文章
- 洛谷 题解 P2731 【骑马修栅栏 Riding the Fences】
简单的开始 完美の开始 这里数组什么的用来干什么后面标注的清楚了 #include<iostream> #include<cstdio> #include<cmath&g ...
- 洛谷p3801:红色的幻想乡
初见完全没有思路.....感觉像是线段树 但二维感觉完全不可做嘛 于是只能去看了看题解 然而还是疯狂爆零+WA.. 和yycc神犇调了两三个小时才调出来... ——————以下个人理解 考虑到每次的修 ...
- P2731 骑马修栅栏 Riding the Fences 题解(欧拉回路)
题目链接 P2731 骑马修栅栏 Riding the Fences 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...
- 洛谷P2731 骑马修栅栏 Riding the Fences
P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题 ...
- 洛谷 P2731 骑马修栅栏 Riding the Fences
P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...
- 内存级别/栅栏 ( Memory Barriers / Fences ) – 翻译
翻译自:Martin Thompson – Memory Barriers/Fences 在这篇文章里,我将讨论并发编程里最基础的技术–以内存关卡或栅栏著称.那让进程内的内存状态对其它进程可见. CP ...
- 洛谷 P2731 骑马修栅栏 Riding the Fences 解题报告
P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...
- 「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径
Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编 ...
- USACO Section 3.3 骑马修栅栏 Riding the Fences
题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...
随机推荐
- Ganglia 安装 No package 'ck' found
安装ConcurrecyKit,下载地址:https://github.com/concurrencykit/ck 编译安装即可 下面是一个歪果仁的解决办法,不过我没用上 I was buildi ...
- 二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041
最大匹配数就等于最大点覆盖,因为在图里面,凡是要覆盖的点必定是连通的,而最大匹配之后,若还有点没有覆盖到,则必定有新的匹配,与最大匹配数矛盾,如果去掉一些匹配,则必定有点没有覆盖到. POJ 1469 ...
- 路飞学城—Python爬虫实战密训班 第三章
路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...
- [BJDCTF2020]Easy MD5
0x00 知识点 password='".md5($pass,true)."' 链接: https://www.jianshu.com/p/12125291f50d ffifdy ...
- [GXYCTF2019]BabySQli
0x00 知识点 emmm这道题目就是脑洞得大,能猜后端源码 0x01 解题 查看源码: base32,base64解码得到 select * from user where username = ' ...
- Vue iview 表单封装验证
以下内容转自iview社区,仅供自己查看使用 Form表单部分 <div> <Form ref="FormOne" :model="FormOne&qu ...
- QMainWindow的空间布局结构
简单讲一下Qt的QMainWindow的结构,Qt的顶级窗口有三种类型,首先是万恶之源(...应该说是大部分控件的父类...)的QWidget,然后是QMainWidget和QDialog,后面两者也 ...
- elastic启动脚本
#!bin/bash export JAVA_HOME=/usr/java/jdk1.8.0_144 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH ...
- Swift 中调试状态下打印日志
首先我们应该知道Swift中真个程序的入口就是在AppDelegate.swift中.所以在打印日志在 AppDelegate.swift中是这样的 import UIKit @UIApplicati ...
- Mac OS 终端利器 iTerm2配置大全
之前一直使用 Mac OS 自带的终端,用起来虽然有些不太方便,但总体来说还是可以接受的,是有想换个终端的想法,然后今天偶然看到一个终端利器 iTerm2,发现真的很强大,也非常的好用,按照网上配置了 ...