这道题的思想是首先我们找到所有的栅栏围成的空间,然后求每一只奶牛在哪几个栅栏空间之中,最后比较他们在的所有栅栏空间-----如果奶牛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】的更多相关文章

  1. 洛谷 题解 P2731 【骑马修栅栏 Riding the Fences】

    简单的开始 完美の开始 这里数组什么的用来干什么后面标注的清楚了 #include<iostream> #include<cstdio> #include<cmath&g ...

  2. 洛谷p3801:红色的幻想乡

    初见完全没有思路.....感觉像是线段树 但二维感觉完全不可做嘛 于是只能去看了看题解 然而还是疯狂爆零+WA.. 和yycc神犇调了两三个小时才调出来... ——————以下个人理解 考虑到每次的修 ...

  3. P2731 骑马修栅栏 Riding the Fences 题解(欧拉回路)

    题目链接 P2731 骑马修栅栏 Riding the Fences 解题思路 存图+简单\(DFS\). 坑点在于两种不同的输出方式. #include<stdio.h> #define ...

  4. 洛谷P2731 骑马修栅栏 Riding the Fences

    P2731 骑马修栅栏 Riding the Fences• o 119通过o 468提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题解 最新讨论 • 数据有问题题 ...

  5. 洛谷 P2731 骑马修栅栏 Riding the Fences

    P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...

  6. 内存级别/栅栏 ( Memory Barriers / Fences ) – 翻译

    翻译自:Martin Thompson – Memory Barriers/Fences 在这篇文章里,我将讨论并发编程里最基础的技术–以内存关卡或栅栏著称.那让进程内的内存状态对其它进程可见. CP ...

  7. 洛谷 P2731 骑马修栅栏 Riding the Fences 解题报告

    P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样 ...

  8. 「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径

    Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编 ...

  9. USACO Section 3.3 骑马修栅栏 Riding the Fences

    题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...

随机推荐

  1. Eclipse反编译插件jad的安装

    Eclipse反编译插件jad的安装 JadClipse是Jad的Eclipse插件,是一款非常实用而且方便的Java反编译插件.时间久了,可能忘记在哪里进行配置了,因此记录下以备后续使用(若需要). ...

  2. svg教程

    实例 <html> <body> <h1>My first SVG</h1> <svg style="border: 1px solid ...

  3. C++ STD Gems04

    count.count_if.all_of.any_of.none_of #include <iostream> #include <vector> #include < ...

  4. Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年

    计算年.月.日需要安装组件包 pip install python-dateutil 当前日期时间 import datetime print datetime.datetime.now() # 20 ...

  5. matlab中自带的sobol的函数提供的sobol序列

    clc; clear all; close all; M=;% 维度,几个参数 nPop=; VarMin=[0.6, 0.10, 0.002, 0.02, 0.17, 0.0, 0.17, 0.0, ...

  6. java内存机制 垃圾回收

    gc机制一 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc ...

  7. 实验吧web-易-拐弯抹角(url伪静态)

    <?php // code by SEC@USTC echo '<html><head><meta http-equiv="charset" c ...

  8. 2020PHP面试-Redis篇

    一.Redis 数据类型 1. string 字符型. 2.hash hash  结构化的对象.  key不可重复 3.list 队列  lpush rpop  lpop rpush 4. set 集 ...

  9. 一天一个设计模式——Prototype 原型模式

    一.模式说明 看了比较多的资料,对原型模式写的比较复杂,个人的理解就是模型复制,根据现有的类来直接创建新的类,而不是调用类的构造函数. 那为什么不直接调用new方法来创建类的实例呢,主要一个原因是如果 ...

  10. POJ 1062:昂贵的聘礼

    昂贵的聘礼 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 40715   Accepted: 11839 Descripti ...