SGU128 Snake
SGU128,题意是给定N个点,问说能不能形成一个闭环G,要求G经过每个点,且在每个点处都有90度的转角,且不能出现自交。
没想出来,通过这提供的思路,由于每个点处都需要90度的转弯,因此每个点处必然有一条横向以及一条纵向的路径穿过,单从某个x来看,由于上述限制,因此需要有偶数个点两两配对。然后通过搜索判断是否连通,最后再借助树状数组判断是否有自交的情况(”+”这种自交形状)出现。
PS: 这里有个GDB的简单教程。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAXN = ; pair<int, int> points[MAXN];
vector<int> x_points[*MAXN], y_points[*MAXN];
int x_link[MAXN], y_link[MAXN];
bool visit[MAXN], towards[*MAXN]; class BinaryIndexedTree {
private:
int *c_, num_;
public:
BinaryIndexedTree() : c_(NULL) {}
BinaryIndexedTree(int num) : num_(num) {
c_ = new int[num_];
memset(c_, , sizeof(int) * num_);
}
~BinaryIndexedTree() {
if (c_ != NULL) {
delete[] c_;
c_ = NULL;
}
}
private:
int lowbit(int x) {
return x & (-x);
}
public:
int Query(int i) {
int res = ;
while (i > ) {
res += c_[i];
i -= this->lowbit(i);
}
return res;
}
int Query(int left, int right) {
return this->Query(right) - this->Query(left - );
}
void Update(int i, int value) {
while (i < num_) {
c_[i] += value;
i += this->lowbit(i);
}
}
}; bool x_cmp(int u, int v) {
return points[u].first < points[v].first;
} bool y_cmp(int u, int v) {
return points[u].second < points[v].second;
} int main()
{
int n;
scanf("%d", &n);
for (int i = ; i < n; i++) {
int a, b;
scanf("%d%d", &a, &b);
a += ;
b += ; points[i].first = a;
points[i].second = b; x_points[a].push_back(i);
y_points[b].push_back(i);
} bool ok = true;
int total_length = ;
memset(x_link, -, sizeof(x_link));
memset(y_link, -, sizeof(y_link)); do {
// x order
for (int i = ; i < * MAXN; i++) {
if (x_points[i].size() > ) {
if (x_points[i].size() & ) {
ok = false;
break;
} sort(x_points[i].begin(), x_points[i].end(), y_cmp); for (int j = ; j < x_points[i].size(); j += ) {
int down = x_points[i][j];
int up = x_points[i][j + ]; total_length += (points[up].second - points[down].second); y_link[down] = up; y_link[up] = down;
}
}
}
if (!ok) break; // y order
for (int i = ; i < * MAXN; i++) {
if (y_points[i].size() > ) {
if (y_points[i].size() & ) {
ok = false;
break;
} sort(y_points[i].begin(), y_points[i].end(), x_cmp); for (int j = ; j < y_points[i].size(); j += ) {
int left = y_points[i][j];
int right = y_points[i][j + ]; total_length += (points[right].first - points[left].first); x_link[left] = right; x_link[right] = left;
}
}
}
if (!ok) break; // search
memset(visit, false, sizeof(visit));
vector<int> Q;
Q.push_back();
visit[] = true; for (int i = ; i < Q.size(); i++) {
if (x_link[Q[i]] == - || y_link[Q[i]] == -) {
ok = false;
break;
} else {
if (visit[x_link[Q[i]]] == false) {
visit[x_link[Q[i]]] = true;
Q.push_back(x_link[Q[i]]);
} if (visit[y_link[Q[i]]] == false) {
visit[y_link[Q[i]]] = true;
Q.push_back(y_link[Q[i]]);
}
}
} for (int i = ; i < n; i++) {
if (visit[i] == false) {
ok = false;
break;
}
} // check self-cross
memset(towards, false, sizeof(towards));
BinaryIndexedTree tree = BinaryIndexedTree(MAXN * );
for (int i = ; i < *MAXN; i++) if (x_points[i].size() > ) {
for (int j = ; j < x_points[i].size(); j += ) {
int down = points[x_points[i][j]].second;
int up = points[x_points[i][j + ]].second; towards[down] = !towards[down];
towards[up] = !towards[up]; tree.Update(down, towards[down] ? + : -);
tree.Update(up, towards[up] ? + : -); if (down + < up - && tree.Query(down + , up - ) > ) {
ok = false;
break;
}
} if (!ok) break;
} } while(); if (ok) {
printf("%d\n", total_length);
} else {
printf("0\n");
}
}
SGU128 Snake的更多相关文章
- SGU Volume 1
SGU 解题报告(持续更新中...Ctrl+A可看题目类型): SGU101.Domino(多米诺骨牌)------------★★★type:图 SGU102.Coprimes(互质的数) SGU1 ...
- [LeetCode] Design Snake Game 设计贪吃蛇游戏
Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...
- Leetcode: Design Snake Game
Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...
- 2101 Problem A Snake Filled
题目描述 “What a boring world!”Julyed felt so bored that she began to write numbers on the coordinate pa ...
- 图像分割之(五)活动轮廓模型之Snake模型简介
在"图像分割之(一)概述"中咱们简单了解了目前主流的图像分割方法.下面咱们主要学习下基于能量泛函的分割方法.这里学习下Snake模型简单的知识,Level Set(水平集)模型会在 ...
- Epic - Snake Sequence
You are given a grid of numbers. A snakes equence is made up of adjacent numbers such that for each ...
- Codeforces Round #290 (Div. 2) A. Fox And Snake 水题
A. Fox And Snake 题目连接: http://codeforces.com/contest/510/problem/A Description Fox Ciel starts to le ...
- 图像切割之(五)活动轮廓模型之Snake模型简单介绍
图像切割之(五)活动轮廓模型之Snake模型简单介绍 zouxy09@qq.com http://blog.csdn.net/zouxy09 在"图像切割之(一)概述"中咱们简单了 ...
- 353. Design Snake Game
贪食蛇. GAME OVER有2种情况,1是咬到自己,2是出界. 1)用QUEUE来保留占据的格子,每走一格就添加1个,然后POll()最后一个. 做一个一样的SET来check要走的格子是不是已经在 ...
随机推荐
- OpenCV和Matplotlib色彩空间模式不一致的问题
当用OpenCV读取彩色图像时,OpenCV是以(BGR)的顺序存储图像数据的,而Matplotlib是以(RGB)的顺序显示图像的. 可以用下面的程序来证明这一点 import cv2 import ...
- 静态页面中如何传json数据
首页传递参数组装成json数据,再编码 var param="{type:'"+type+"',text:'"+select_text+"',sele ...
- 如何清除Linux 登陆信息及日志
本文介绍下,在linux中,如何清除访问日志.登陆日志以及曾用命令的方法.有需要的朋友,参考下吧. 在linux系统中,如何清除访问日志.登陆日志及曾使用过的命令呢? 本文介绍的方法,将删除所有日志, ...
- mysql 拷贝表插入新的表
insert into table1 select * from table; insert into talble set name = value;
- 淘宝IP地址库API接口(PHP)通过ip获取地址信息
淘宝IP地址库网址:http://ip.taobao.com/ 提供的服务包括: 1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家.省.市和运营商. 2. 用 ...
- Linux进程间通信IPC学习笔记之管道
基础知识: 管道是最初的Unix IPC形式,可追溯到1973年的Unix第3版.使用其应注意两点: 1)没有名字: 2)用于共同祖先间的进程通信: 3)读写操作用read和write函数 #incl ...
- WPF自定义控件之带倒计时的按钮--Button
1.说明 之前做过一个小项目,点击按钮,按钮进入倒计时无效状态,计时完成后,恢复原样,现在就实现该效果---带倒计时的按钮 2.效果 1)正常状态 2)MouseOver( ...
- spring接收参数
public class LogonModel { private String UserName; private String Password; public String getUserNam ...
- PHP - PDO 之 mysql 基础操作
<?php /* pdo 学习 */ $dsn = 'mysql:host=localhost;dbname=cswl';//构建连接dsn $db = new pdo($dsn,'root', ...
- vijos 1085 Sunnypig闯三角关
{这个题5个正确,五个超时,不要盲目相信我的代码,谁有更好的算法或者优化请留言,(*^__^*) 嘻嘻……} 背景 贪玩的sunnypig请Charles为他打造一个奇幻世界,Charles欣然答应了 ...