USACO 1.3 Wormholes - 搜索
Wormholes
Farmer John's hobby of conducting high-energy physics experiments on weekends has backfired, causing N wormholes (2 <= N <= 12, N even) to materialize on his farm, each located at a distinct point on the 2D map of his farm (the x,y coordinates are both integers).
According to his calculations, Farmer John knows that his wormholes will form N/2 connected pairs. For example, if wormholes A and B are connected as a pair, then any object entering wormhole A will exit wormhole B moving in the same direction, and any object entering wormhole B will similarly exit from wormhole A moving in the same direction. This can have rather unpleasant consequences.
For example, suppose there are two paired wormholes A at (1,1) and B at (3,1), and that Bessie the cow starts from position (2,1) moving in the +x direction. Bessie will enter wormhole B [at (3,1)], exit from A [at (1,1)], then enter B again, and so on, getting trapped in an infinite cycle!
| . . . .
| A > B . Bessie will travel to B then
+ . . . . A then across to B again
Farmer John knows the exact location of each wormhole on his farm. He knows that Bessie the cow always walks in the +x direction, although he does not remember where Bessie is currently located.
Please help Farmer John count the number of distinct pairings of the wormholes such that Bessie could possibly get trapped in an infinite cycle if she starts from an unlucky position. FJ doesn't know which wormhole pairs with any other wormhole, so find all the possibilities.
PROGRAM NAME: wormhole
INPUT FORMAT:
| Line 1: | The number of wormholes, N. |
| Lines 2..1+N: | Each line contains two space-separated integers describing the (x,y) coordinates of a single wormhole. Each coordinate is in the range 0..1,000,000,000. |
SAMPLE INPUT (file wormhole.in):
4
0 0
1 0
1 1
0 1
INPUT DETAILS:
There are 4 wormholes, forming the corners of a square.
OUTPUT FORMAT:
| Line 1: | The number of distinct pairings of wormholes such that Bessie could conceivably get stuck in a cycle walking from some starting point in the +x direction. |
SAMPLE OUTPUT (file wormhole.out):
2
OUTPUT DETAILS:
If we number the wormholes 1..4 as we read them from the input, then if wormhole 1 pairs with wormhole 2 and wormhole 3 pairs with wormhole 4, Bessie can get stuck if she starts anywhere between (0,0) and (1,0) or between (0,1) and (1,1).
| . . . .
4 3 . . . Bessie will travel to B then
1-2-.-.-. A then across to B again
Similarly, with the same starting points, Bessie can get stuck in a cycle if the pairings are 1-3 and 2-4 (if Bessie enters WH#3 and comes out at WH#1, she then walks to WH#2 which transports here to WH#4 which directs her towards WH#3 again for a cycle).
Only the pairings 1-4 and 2-3 allow Bessie to walk in the +x direction from any point in the 2D plane with no danger of cycling.
Submission file Name: USACO Gateway | Comment or Question
(转自[USACO])
讲一下题目大意。Farmer John(USACO的标志人物啊)特别喜欢做实验,使得农场上出现了N(N <= 12)个虫洞,现在将这N个虫洞两两配对,配对了的虫洞从其中一个进入就会从对应的一个虫洞出来。Bessie在田园中总是向x轴的正方向前进。John想知道,有多少种虫洞的配对方案可以让Bessie在田园中某一个地方出发,会陷入死循环。
很明显的搜索(数据范围小),因为(1,2)(3,4)和(3,4)(1,2)是同一种匹配,所以每一次搜索的时候就找到编号最小的一个虫洞和其他的虫洞匹配。
接下来就是判断是否会陷入死循环。还算比较好想。首先给每个虫洞预处理出一个right,表示从它出来,往右走遇到的第一个虫洞的编号,如果不存在,就记个0吧。然后用个数组记录一下类似于Tarjan的时间戳的一个东西,每次循环访问的时候记一个编号(当然设成一样的),如果下一虫洞没有访问,那么就把编号设成当前的编号,否则判断它是否和现在的编号相等,如果相等,就说明会陷入死循环。
Code
/*
ID:
PROG: wormhole
LANG: C++11
*/
/**
* USACO
* Accpeted
* Time:0ms
* Memory:4184k
*/
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define INF 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class Point {
public:
int x;
int y;
int id;
boolean operator < (Point another) const {
if(this->y != another.y) return this->y < another.y;
return this->x < another.x;
}
}Point; int n;
int* onright;
Point* ps; inline void init(){
readInteger(n);
ps = new Point[(const int)(n + )];
onright = new int[(const int)(n + )];
for(int i = ; i <= n; i++){
readInteger(ps[i].x);
readInteger(ps[i].y);
ps[i].id = i;
onright[i] = ;
}
} int* matches;
boolean* seced;
int res; boolean check(){
int vis[(const int)(n + )];
memset(vis, , sizeof(vis));
vis[] = -;
for(int i = ; i <= n; i++){
if(vis[i] != ) continue;
int p = i;
while(vis[p] == ){
vis[p] = i;
p = onright[p];
if(seced[p]) p = matches[p];
}
if(vis[p] == i) return true;
}
return false;
} void search(int choosed){
if(choosed + > n){
if(check()) res++;
return;
}
int sta;
for(int i = ; i <= n; i++)
if(!seced[i]){
sta = i;
break;
}
seced[sta] = true;
for(int i = sta + ; i <= n; i++){
if(!seced[i]){
matches[sta] = i;
matches[i] = sta;
seced[i] = true;
search(choosed + );
seced[i] = false;
}
}
seced[sta] = false;
} inline void solve(){
matches = new int[(const int)(n + )];
seced = new boolean[(const int)(n + )];
memset(seced, false, sizeof(boolean) * (n + ));
sort(ps + , ps + n + );
for(int i = ; i < n; i++){
if(ps[i + ].y == ps[i].y){
onright[ps[i].id] = ps[i + ].id;
}
}
search();
printf("%d\n", res);
} int main(){
freopen("wormhole.in", "r", stdin);
freopen("wormhole.out", "w", stdout);
init();
solve();
return ;
}
USACO 1.3 Wormholes - 搜索的更多相关文章
- [题解]USACO 1.3 Wormholes
Wormholes Farmer John's hobby of conducting high-energy physics experiments on weekends has backfire ...
- USACO 1.3 Wormholes
Wormholes Farmer John's hobby of conducting high-energy physics experiments on weekends has backfire ...
- USACO Section1.3 Wormholes 解题报告
wormhole解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------- ...
- USACO 完结的一些感想
其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...
- P1466 集合 Subset Sums 搜索+递推+背包三种做法
题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...
- 「Luogu P2845 [USACO15DEC]Switching on the Lights 开关灯」
USACO的又一道搜索题 前置芝士 BFS(DFS)遍历:用来搜索.(因为BFS好写,本文以BFS为准还不是因为作者懒) 链式前向星,本题的数据比较水,所以邻接表也可以写,但是链式前向星它不香吗. 具 ...
- USACO 1.3... 虫洞 解题报告(搜索+强大剪枝+模拟)
这题可真是又让我找到了八数码的感觉...哈哈. 首先,第一次见题,没有思路,第二次看题,感觉是搜索,就这样写下来了. 这题我几乎是一个点一个点改对的(至于为什么是这样,后面给你看一个神奇的东西),让我 ...
- USACO 6.3 章节 你对搜索和剪枝一无所知QAQ
emmm........很久很久以前 把6.2过了 所以emmmmmm 直接跳过 ,从6.1到6.3吧 Fence Rails 题目大意 N<=50个数A1,A2... 1023个数,每个数数值 ...
- POJ 1176 Party Lamps&& USACO 2.2 派对灯(搜索)
题目地址 http://poj.org/problem?id=1176 题目描述 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码. 这些灯都 ...
随机推荐
- Oracle体系结构之oracle密码文件管理
密码文件 密码文件作用: 密码文件用于dba用户的登录认证. dba用户:具备sysdba和sysoper权限的用户,即oracle的sys和system用户. 本地登录: 1)操作系统认证: [or ...
- AmazonOrder xml web语义化
XML Processing Modules — Python 3.7.1 documentation https://docs.python.org/3.7/library/xml.html#xml ...
- sql 对某列取值进行if判断
select if(area_id =350000, 1, 2) as area_id from my_table 取地区编号为350000的设置成 1, 其他的设置成2
- Infopath表单&Reproting Service在IE11下问题解决
一.打开表单出现错误:“对象不支持“addEventListener”属性或方法”错误 解决方法: 1. IE11浏览器--->选项 2. 勾选"在兼容性视图中显示intranet站点 ...
- 仿照hibernate封装的一个对数据库操作的jdbc工具类
package project02_Order_management.util; import java.io.IOException; import java.lang.reflect.Field; ...
- python框架之Django(2)-简单的CRUD
写一个简单的项目小例子来了解Django中的O/RM操作 前戏 创建app #在Django项目根目录下执行 python3 manage.py startapp [app name] 配置数据库连接 ...
- python对象反射和函数反射
python的对象反射功能,经常在编程时使用.相比较其它的编程语言使用非常方便.反射就是用字符串来操作对象或者类,模块中的成员. 一.对象的反射 反射功能的实现,由这4个内置函数来实现(hasattr ...
- [LeetCode] 190. Reverse Bits_Easy tag: Bit Manipulation
Reverse bits of a given 32 bits unsigned integer. Example: Input: 43261596 Output: 964176192 Explana ...
- Selenium Webdriver——操作隐藏的元素(四)
页面上弹出的对话框是自动化测试经常会遇到的一个问题:很多情况下对话框是一个iframe,如上一节中介绍的例子,处理起来稍微有点麻烦:但现在很多前端框架的对话框是div 形式的,这就让我们的处理变得十分 ...
- linux中的查找命令
which命令:使用which命令可以看到某个系统命令是否存在,以及执行的到底是哪一个位置上的命令.在PATH指定的路径中进行搜索, 返回第一个搜索结果. which grep /bin/grep ...