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的更多相关文章

  1. SGU Volume 1

    SGU 解题报告(持续更新中...Ctrl+A可看题目类型): SGU101.Domino(多米诺骨牌)------------★★★type:图 SGU102.Coprimes(互质的数) SGU1 ...

  2. [LeetCode] Design Snake Game 设计贪吃蛇游戏

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  3. Leetcode: Design Snake Game

    Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...

  4. 2101 Problem A Snake Filled

    题目描述 “What a boring world!”Julyed felt so bored that she began to write numbers on the coordinate pa ...

  5. 图像分割之(五)活动轮廓模型之Snake模型简介

    在"图像分割之(一)概述"中咱们简单了解了目前主流的图像分割方法.下面咱们主要学习下基于能量泛函的分割方法.这里学习下Snake模型简单的知识,Level Set(水平集)模型会在 ...

  6. Epic - Snake Sequence

    You are given a grid of numbers. A snakes equence is made up of adjacent numbers such that for each ...

  7. 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 ...

  8. 图像切割之(五)活动轮廓模型之Snake模型简单介绍

    图像切割之(五)活动轮廓模型之Snake模型简单介绍 zouxy09@qq.com http://blog.csdn.net/zouxy09 在"图像切割之(一)概述"中咱们简单了 ...

  9. 353. Design Snake Game

    贪食蛇. GAME OVER有2种情况,1是咬到自己,2是出界. 1)用QUEUE来保留占据的格子,每走一格就添加1个,然后POll()最后一个. 做一个一样的SET来check要走的格子是不是已经在 ...

随机推荐

  1. [java学习笔记]java语言核心----面向对象之static关键字

    static关键字用处 用于修饰成员变量和成员函数 被修饰后的成员具有以下特点: 随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用 使用注意 静态方法只能访问静态成员:非静态方 ...

  2. javascript之数据推送

    我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...

  3. 【Qt】关于Qt【转】

    什么是Qt Qt是一个针对桌面.嵌入式.移动设备的一个跨平台的应用程序开发框架,支持的平台包括Linux.OS X.Windows.VxWorks.QNX.Android.iOS.BlackBerry ...

  4. linux之cat命令

    1. cat 接普通文件名,会把文件内容打印到屏幕:2. cat > file,这个可以向文件“file”写入内容,最后按 Ctrl + D 结束输入,会将你输入的数据保存到文件. cat主要有 ...

  5. Nat网络地址转换

    Nat中的术语 -------------------------------------------------------------------------------------------- ...

  6. DICOM开源库

    转载于 http://blog.csdn.net/jackmacro/article/details/5850142 Developers used to search for libraries , ...

  7. 学习VirtualEnv和Nginx+uwsgi用于django项目部署

    以下叙述中用到的操作系统:Linux CentOS 6.X. 最近几天了解一下VirtualEnv,Apache+Daemon mode,Nginx+uwsgi的概念,并且在项目中实验性部署了一下(目 ...

  8. esp8266的STM32驱动

    esp8266的STM32驱动,数据发送接收由DMA完成,释放CPU. 目前只能发送返回消息为成功或失败的AT命令,并判断是否成功,详见esp8266_cmd():其它返回消息不可预知的命令(如查看A ...

  9. Hadoop学习---安装部署

    hadoop框架 Hadoop使用主/从(Master/Slave)架构,主要角色有NameNode,DataNode,secondary NameNode,JobTracker,TaskTracke ...

  10. iOS实例下载:使用腾讯的SDK将新浪微薄嵌入到应用中

    最近在做应用中添加SNS分享功能,只需要分享功能,腾讯的SDK和Demo还是挺直观的,看了下基本上就能用了,而新浪的Oauth认证看了个例子是跳出程序到Web上去认证的,体验很不好.不过Oauth认证 ...