[Stl && проблема решения] лед

тема Портал

Тема Описание:

Бесси на замерзшем озере для купания, озеро может быть представлено в виде двумерной плоскости, координатно диапазон -1000000000 ... 1000000000.

N на озере (1 <= N <= 20000) с каменным положением (пронумерованных от 1 до N), другое место лед.

Из-за Бесси технику катания не достаточно хорошо, она проталкивается через скалу рядом с его собственным, опираясь на силы реакции вперед в одном направлении, прежде чем встретил новый камень, Бесси не перестанет приходить. (Конечно же, в конце концов останавливается на сетке в блоке камня) не может быть рассчитана в связи со сложностью угла Бесси, она была только в состоянии переместить грузовик в четырех направлениях.

Очевидно, что Бесси не может пересечь скалы, поэтому Бесси может скользить только в трех направлениях.
Катание на коньках не без риска, после того, как Бесси скольжения в определенном направлении , должны быть в состоянии поразить скалу, поэтому она должна быть очень осторожным.

Рассмотрим следующую ситуацию, Бесси ее желаемое конечное положение достигает восток (х = 5, у = 1 ), (. = Лед, камень * =, B = Бесси, G = назначения) , если она прямо на восток скольжения, то она будет скользить целевой позиции, потому что она остановилась камень ударил его головой, программа способна достичь целевого положения заключается в следующем:
Здесь Insert Picture Описание
в (а) в Бесси только на север, восток и юг или направления, но только на севере , чтобы остановить, чтобы быть в состоянии поразить скалу, в (б), так же она может идти только на восток.

Для ввода, камень в точке с координатами я X_i, Y_i положение, (- 1000000000 <= X_i <= 1000000000; -1000000000 <= Y_i <= 1000000000), нет двух камней в том же положении, от Bessie Bx, К начальное положение (начальная точка должна быть рядом с камнем), целевая позиция Бесси Gx, Gy (-1000000000 <= Сх <= 1000000000; -1000000000 <= Гр <= 1000000000).

Бесси не возражали долгое время катания, однако, он толкал вперед силу реакции полагаться на камень уставшей. FJ очень обеспокоен здоровьем Бесси, Бесси не менее он хотел бы знать, сколько раз нажать на камень, чтобы добраться до финиша.


Анализ:

Основная идея этой проблемы , чтобы найти число камней в каждой строке каждого столбца, если я мог бы найти камень, мы можем определить положение , достигнутое после слайда. Ну, на этот раз, мы можем написать 12-полтора , чтобы решить эту проблему (конечно, неверно ..), но 12-половина суммы кода немного большим, мы рассмотрим , как улучшить.

В самом деле, вы можете использовать s е T задавать и м п карта Оптимизация

s е T задавать представляет соответствующие координаты каждой строку хранит камень
м п карта есть число шаговкаждый соответствующий набор записей

Является ли на самом деле м п карта множества s е T задавать процесс

Затем мы используем СТЛ, половина содержания будет опущено, так как СТЛ встроен в дихотомии.

  • как s е T задавать и м п карта в бинарном поиске его?
    1, для таких, отображающего этого уникального набора ключевых слов набора, lower_bound, upper_bound возвращает итератор такого же, Вэлы ключевого слово не существует в коллекции, возвращает оба результата, которые в соответствии с заданной если коллекцией Сравните сравнения, до тогопервый элемент не является Вал (то есть, послеили равна, если меньшесоответствии с типом по умолчаниюсравнения, функция возвращает наименьший элемент ≥val);
  1. Если ключ существует в коллекции в Вале, LOWER_BOUND вернуть VAL сам ключевое слово итератор, upper_bound вал возвращает следующий ключевой элемент итератор.
  2. Времена ключевого слово появляется в наборе могут быть разделены в соответствии с ключевым словом: Вэл ключевым слова появляется в коллекции, но она уникальна, и SET этого случая, похожий на карту ситуации;
  3. Вал ключевое слово появляется в коллекции, происходят более чем один раз, и в этом случае первое ключевое слово lower_bound вернуть вал, соответствующий итератора происходит, возвращает итератора upper_bound, заднее положение, соответствующее положению первого ключевого слова Val Val не; ключевое слово вал не в наборе, то же отображение, в этом случае множество.

Комплексный взгляд на: lower_bound, upper_bound функции независимо от того , какие обстоятельства, следующие условия:
Итератор (Val) ≤Iterator (lower_bound) ≤Iterator (upper_bound)
является LOWER_BOUND, верхний и нижний пределы диапазона СОСТАВЛЯЮЩЕЙ upper_bound всегда представляют собой обоснованную итерацию интервал (equal_range возвращаемого значение), длина интервала представляет число итераций Вэл ключевого слова появляется в коллекции.

Ну, давайте начнем формальный анализ:
потому что темы для координации очень больших размеров, но и камень , но только максимум 20000, так что мы можем начать с камня.
Отображение координат , чтобы установить связь с Дискретизирует камень с картой.

Коллекция представляет собой набор по умолчанию от мало до велика, так что это тоже сложный характер бинарного поиска, мы можем также использовать систему происходит с бинарным поиском, чтобы посмотреть на ближайший камень может быть.

  • Как найти местоположение камня? ?
    Вот пример , приведенный выше ищет:
node go_up(node k){
    set<int> y=rock_x[k.fi];//找到相应的列
    it=y.upper_bound (k.se) ;//找到石头
    if (it==y.end()||(*it)-k.se<=1) return b;//不符合情况
    return node(k.fi,(*it)-1);//返回
}

BFS на самом деле голый BFS, главным образом, на рожон.


Код

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef pair<int , int > node; 
int n;
map < int , set < int > > rock_x;
map < int , set < int > > rock_y;
queue < node > q;
map < node , int > dis;
node b,g;
set < int > :: iterator it;//表示是复制的来的 
node go_up(node k){
    set<int> y=rock_x[k.fi];
    it=y.upper_bound (k.se) ;
    if (it==y.end()||(*it)-k.se<=1) return b;
    return node(k.fi,(*it)-1);
}//往上查找
node go_down(node k){
    set<int> y=rock_x[k.fi];
    it=y.upper_bound (k.se) ;
    if (it==y.begin()||(k.se-(*(--it))<=1)) return b;
    return node(k.fi,(*it)+1);
}//往下查找
node go_left(node k){
    set<int> x=rock_y[k.se];
    it=x.upper_bound (k.fi) ;
    if (it==x.begin()||(k.fi-(*(--it))<=1)) return b;
    return node((*it)+1,k.se);
}//往左查找
node go_right(node k){
    set<int> x=rock_y[k.se];
    it=x.upper_bound (k.fi) ;
    if (it==x.end()||((*it)-k.fi<=1)) return b;
    return node((*it)-1,k.se);
}//往右查找
int main(){
	freopen("ice..in","r",stdin);
	freopen("ice..out","w",stdout);
	scanf("%d %d %d %d %d",&n,&b.fi,&b.se,&g.fi,&g.se);
    for (int i=1,x,y;i<=n;i++)
      scanf("%d %d",&x,&y),rock_x[x].insert(y),rock_y[y].insert(x);//建立每一个石头的行列的索引
    q.push(b);
    dis[b]=0;
    while (!q.empty()){
	    node x=q.front();
	    q.pop();
	    node xx;
	    xx=go_up(x);
	    if (xx!=b&&!dis[xx]) q.push(xx),dis[xx]=dis[x]+1;
	    xx=go_down(x);
	    if (xx!=b&&!dis[xx]) q.push(xx),dis[xx]=dis[x]+1;
	    xx=go_left(x);
	    if (xx!=b&&!dis[xx]) q.push(xx),dis[xx]=dis[x]+1;
	    xx=go_right(x);
	    if (xx!=b&&!dis[xx]) q.push(xx),dis[xx]=dis[x]+1;
	    if (dis[g]) break;
	}//bfs查找过程
	printf("%d",dis[g]);//输出
	fclose(stdin);
	fclose(stdout);
	return 0;
}

Пожалуйста, поддержите меня

рекомендация

отblog.csdn.net/huang_ke_hai/article/details/88913611