• Как исправить код?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Похоже проблема в непонимании параметров string::insert. Там передается индекс, в который и вставляется строка. Т.е. новые данные будут по этому индексу. Фактически, они вставляются перед символом на этой позиции.

    Оно уже делает ровно то, что вам надо, не нужно делать там k[i]-1 и разбирать отдельно случай k[i]==0.
    Ответ написан
    Комментировать
  • Почему вылазит link error(не видит вирутальные методы?)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Потому что шаблон.

    Надо или весь класс определять в хедере, или в array.cpp указывать компилятору генерировать инстанс шаблона с параметром, который нужен в другом cpp файле:
    using Array<int>;

    То же и для очереди.

    Происходит это потому, что компилятор генерирует шаблоны лениво - только когда они нужны. Вот, компилируя array.cpp он не видет вообще ни одного использования шаблона и не генерирует ничего. В каком-нибудь main.cpp у него есть объявление из array.h и использование шаблона. Он и генерирует объявления методов. Но определения-то нигде нет. Оно в array.obj должно быть по вашему замыслу, а там пусто.
    Ответ написан
    1 комментарий
  • Поиск кратчайшего пути в ориентированном графе с цветными вершинами и дугами?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Тут надо сделать из графа на N вершин граф на N^2 вершин. Граф-то совсем маленький. Каждая вершина нового графа соответствует паре вершин изначалного графа (x, y) и обозначает, что фишки стоят в вершинах x и y соответственно. Переходы в новом графе делаются из переходов в изначальном: из (x, y) можно перейти в (x, z), если в изначальном графе есть дуга y->z и ее цвет совпадает с вершиной x. Аналогично из (x,y) можно перейти в (z,y), если есть дуга x->z и ее цвет совпадает с y.

    В этом графе уже можно любым известным вам способом искать путь. Только тут конечных вершин будет сразу много: это все пары (x,y), где x или у - конечная вершина в графе. Можно или добавить новую конечную вершину и соединить с ней все вот эти вот, или прямо в алгоритме исправить условие останова.

    Можно граф не хранить явно. Если у вас BFS, то храние в очереди сразу пару чисел. Внутри перебирайте переходы из первой а потом из второй вершины и делайте их только если условие на совпадение цвета выполняется. Ну и, все массивы хранящие расстояние и т.п. в алгоритме будут уже двумерные.
    Ответ написан
    Комментировать
  • Как найти такую вершину заданного графа, которая принадлежит каждому пути между двумя выделенными?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Все такие вершины являются точками сочленения. Ведь, удалив такую вершину из графа больше не будет пути между двумя вершинами, а значит граф развалился на новые компоненты связности. Есть алгоритм на основе Dfs, который их ищет. Это все работает за O(V+E). Предложенный вами алгоритм с удалением по одной вершине вполне себе работает, но будет медленнее: O(V(V+E)). Для небольших графов может и подойдет.

    Потом надо найти путь между заданными вершинами и вывести в ответ точки сочленения. Лучше ищите путь тем же DFSом, что и ищите точки сочленения. Так путь будет идти по дереву DFS. Надо найти в нем LCA двух искомых точек (Пик пути, после которого он пойдет вниз в другую ветку).

    Важно, выводить надо не все точки сочленения, а только те, у которых из следующей вершины в пути, она же будет ребенком в дереве DFS, нельзя вернутся назад выше текущей точки сочленения. Т.е. точка назначена алгоритмом точкой сочленения из-за ребенка именно в сторону искомой вершины.
    Ответ написан
    Комментировать
  • Почему выбивает исключение на моменте деления изображения на равные блоки?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Наверно, в коде еще есть ошибки, но вот тут:
    vector <double> variances;
    for (int i = 0; i < num_blocks; i++) {
        Scalar mean, stddev;
        meanStdDev(block[i], mean, stddev);
        variances[i] = stddev.val[0];
    }


    Вы записываете в пустой вектор variances по индексу i. Надо или делать push_back в вектор, или выделить его сразу размера num_blocks. Например, так:
    vector <double> variances(num_blocks);

    Еще перепроверьте, что у вас rows/cols не перепутано.
    Ответ написан
    Комментировать
  • Есть ли флаг компиляции gcc, чтобы неявное приведение типов выводилась как ошибка?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    -Wconversion -Warith-conversion
    Ответ написан
    Комментировать
  • Почему не считывает все нажатия вне event loop SFML?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    pollEvent возвращает сообщение из очереди, пока они там есть. В очереди их может оказаться несколько. Именно поэтому там цикл while. А код за циклом обрабатывает только одно - последнее - сообщение. Судя по наблюдаемому вами поведению, в очереди оказывается несколько сообщений.
    Ответ написан
  • Как отправить клик мышью в чужое SDL окно не двигая системную мышь через winapi?

    wataru
    @wataru Автор вопроса
    Разработчик на С++, экс-олимпиадник.
    После более пристального ковыряния в spy++ я выяснил, что чужое окно получает WM_MOUSELEAVE после каждого моего SendMessage с WM_MOUSEMOVE или WM_LBUTTONDOWN/UP.

    Видимо, оно подписывается у системы на это через TrackMouseEvent.

    Это лишнее сообщение все портит и приходит даже если посылать сообщения через SendMessage без задержек.

    Похоже, придется ковырятся с dll injection, чтобы перехватывать WM_MOUSELEAVE и игнорировать его.
    Ответ написан
    Комментировать
  • Почему не работает GetPixel?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    GetPixel принимает сначала x, потом y. У вас там Height и Width не в том порядке переданы.

    Это будет ошибкой, если одна из сторон более чем в 2 раза больше другой. Это может быть, если у вас широкоформатный монитор.

    У вас там битмап сохраняется в sceen2.png - оно там что-то сохранило вообще? Иначе проблема может быть не GetPixel, а с самим хБитмапом.

    Edit:

    Еще проблема может быть с масштабированием. В результате GetSystemMetrics(SM_CYSCREEN) возвращает не то, что вам надо и BitBlt не срабатывает из-за слишком большого размера.

    Попробуйте вызвать SetProcessDPIAware.

    Еще может быть проблема, что вы SelectObject делаете 2 раза с одним и тем же membit. Надо во второй раз что-то другое подставлять, чтобы HBitmap освободить. Иначе оно, похоже, так и остается привязано к DC.

    Вот мой рабочий код:
    HBITMAP GameManager::GetScreenshot(HWND window) {
    	HDC hScreenDC = GetDC(window);
    	HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    	RECT window_rect;
    	GetClientRect(window, &window_rect);
    	int width = window_rect.right - window_rect.left;
    	int height = window_rect.bottom - window_rect.top; 
    	int result_width = width;
    	int result_height = height;
    	
    	HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, result_width, result_height);
    	HBITMAP hOldBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hBitmap));
    	StretchBlt(hMemoryDC, 0, 0, result_width, result_height, hScreenDC, 0, 0, width, height, SRCCOPY);
    	hBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hOldBitmap));
    	DeleteDC(hMemoryDC);
    	DeleteDC(hScreenDC);
    	return hBitmap;
    }
    Ответ написан
    1 комментарий
  • Как растягивать прямоугольники до полного замощения области?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Не знаю, насколько оптимальное решение это будет давать, но раздувайте прямоугольники по чуть-чуть.

    Пусть у прямоугольников будут степени свободы - верх,лево,низ,право. Изначально все прямоугольники раздуваются во все 4 стороны.

    Дальше, представьте, что каждый прямоугольник раздувается на 1 пиксель во все стороны за 1 тик.

    Перебрав все пары прямоугольников вы можете для них подсчитать через какое время эта парочка столкнется. Важно, надо считать только варинаты, где прямоугольники раздуваются друг на встречу другу (хотя бы один из пары), а то у вас может все время быть время 0 - два прямоугольника сейчас касаются.

    Найдите минимальное время для всех пар. "Отмотайте" это время вперед - раздуйте все прямоугольники на это количество пикселей по всем активным степеням свободы. У двух пересекающихся отберите свободу раздуваться в направлениях, где они коснулись. Если они коснулись по углу, то у вас это будет событие: или они встретились по горизонтали, или по вертикали. Именно эти степени свободы и отбираете.

    Повторяйте пока есть хоть одна степень свободы где-то.

    Ну и еще надо учитывать пересечения с гарницей поля - точно так же. Считаете время до столкновения.

    Может быть так, что пройдет время 0, если куча прямоугольников коснутся в одно и то же время. Это нормально, вы не перематывая время в обработке этого события дезактивируете какие-то степени свободы у каких-то прямоугольников.

    Можно просто после каждого столкновения снова искать минимум по всем парам прямоугольников. Можно это соптимизировать знатно через приоритетную очередь, но вряд ли у вас там тысячи прямоугольников и вам это надо делать.

    Еще прикол, если прямоугольники пересекутся через пол тика - между ними всего один пиксель. Тут надо будет двигать только один из двух, скажем, с тот у кого номер меньше.

    В примере с картинки вы через 0 тиков зафиксируете, допустим, вертикальные границы и потом найдете. что через какое-то время один из прямоугольников упрется в стену. Раздуете оба прямоугольника, зафиксируете упершийся. Дальше, если все симметрично, то второй прямоугольник через 0 тиков тоже упрется в стену.

    Правда у этого метода есть проблема Например, вот такая картинка:
    AA.B
    ...B
    C...
    C.DD


    Тут прямоугольники можно чуть чуть раздуть до упирания, но при определенных пропорциях в центре останется пустое место, при чем все 4 окна будут сцеплены между собой. Не уменьшая изначальные окна его никак не убрать.
    Ответ написан
    Комментировать
  • Реализация лабиринта по алгоритму Уилсона. Как сделать это в C# WinForms?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    В чем проблема перевести с lua на C#?

    Там в алгоритме ничего сверх сложного и какой-то встроенной библиотеки не используется. Понятно, что MazeGrid - это двумерный массив? Aux - это класс с методами createGrid (возвращает двумерный массив класса с полями visited, right_wall, bottom_wall), wilson (реализация алгоритма) и всякие вспомогателные hashKey/deHashKey. Еще есть поля width/height/sx/sy.

    Сам алгоритм в wilson() использует циклы while и for, if, elseif - все это переводится на C# не задействуя мозг вообще. Чисто механически. Ну, разве что о типах переменных чуть чуть подумать придется. Но, ясно же, что dir - это строка, isMoved - bool.

    Потом, когда вы это все переведете, можно начинать улучшать код. Типа вместо строк для направлений использовать enum.
    Ответ написан
    Комментировать
  • Вычислить исходные величины на основе измерений с погрешностью - как называется и решается такая задача?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Это называется кластеризация.

    Восстановить точное значение вы никогда не сможете, но можно взять среднее в каждом кластере. Такими измерениями занимается статистика
    Ответ написан
    Комментировать
  • Можно так сделать с interface?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    По уму, вам надо продумать ваш интерфейс. И тогда подобных извращений не понадобится. Дабавьте туда какой-нибудь способ для итерации по структуре данных для вывода. Или вообще сделайте метод ToString, который бы возвращал строковое представление внутренней структуры для вывода. Это все, естественно, виртуальные публичные методы, переопределенные в двух реализациях.

    То же и со вводом. Если надо как-то во внутренности очереди залезать и обычными push это не сделать, то, например, передавайте в метод CreateFromData() вектор введенных пользователем значений.
    Ответ написан
    Комментировать
  • Почему скалярное произведение не нормализованных и коллинеарных векторов разное при изменении их точек?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Ну, скалярное произведение вектора самого на себя - даст квадрат его длины по определению (|a|*|a|*cos(0)). Если менять точки - меняется длина вектора - меняется скалярное произведение.
    Ответ написан
    Комментировать
  • Как сделать какую-нибудь многозадачность на ардуино?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно поменять логику. Включили мотор и постоянно меряете расстояние. Как домеряли до 35см - остановились.

    Можно перед циклом один раз померять - решить, а надо ли вообще мотор включать. Внутри, чтоб электричество зря не жечь, можно даже между вычислениями расстояния сколько-то спать. Смотрите там из расстояния - если оно сильно больше 35 - спите подольше.
    Ответ написан
    2 комментария
  • Почему автодополнение не предлагает мне поля структуры?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы хотите вернуть T. У Node - это член Data. Вот и возвращайте _node->data, или какой там у вас смысл у _node. Пока странно, вы наследуетесь от Array, но никак его не используете. По идее надо возвращать первый элемент в массиве.

    Да, еще, по английски правильно capaCity, а не capaSity.
    Ответ написан
  • Импликация (следование) в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нету в C++ отдельных операторов для этих логических функций. Потому что их все можно составить из И, ИЛИ и НЕ.

    Так, импликация - это !a || b. Эквивалентность - можно просто сравнить 2 переменные: a == b.
    Ответ написан
    1 комментарий
  • Как можно перебирать слова в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Раз у вас во вводе коды каждого символа разделены пробелами, то все просто. Заведите в программе map<wstring, wchar> и где-то в начале напишите 33 строчки вида:
    dict[L"•−"] = L'А';

    Потом входную строку разбейте на части по проблелам. Руками, циклом. Указатель-индекс будет указывать на первый необработанный символ. Найдите первый пробел или конец строки начиная с этой позиции. Кусок между двумя позициями - это текущий код. Его с помощью map'а выше переводите в символ. Сдвигайте индекс первого необработанного символа на позицию после пробела. Ну и аккуратно смотрите, если первый необработанный - пробел, то это пробел между словами - его как есть и выводите, сдвигая индекс необработанного символа на 1.
    Ответ написан
  • Почему не вызывается конструктор копирования при инициализации переменной другим объектом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Тут сработало copy elision.

    operator& не создает никакого временного Query, а работает сразу с Query в месте его вызова. Поэтому конструктор в пункте 8 создает уже результат.
    Ответ написан
    Комментировать
  • Что делать с этой проблемой?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Исходник в кодировке utf. 'А' действительно занимает 2 байта. Что видит компилятор? Видит 2 байта между кавычками и ругается.

    setlocale() - эта функция во время исполнения программы настроит, в какой кодировке у вас будет просиходить ввод/вывод с консоли. На кодировку исходника оно никак не влияет.

    Тут 2 варианта решения: Или поменяйте кодировку исходника и настройки локали, чтобы 'А' занимало один байт, или работайте с wstring.

    Чтобы не путаться с кодировками, напишите программу, которая выводит численное значение байт прочитанной строки. Запустите ее, введите туда 'А', смотрите, что оно выводит. Поэксперементируйте с разными настройками setlocale(). Если выводит 2 байта - вот эти два байта надо писать в case и использовать wstring. Если выводит один байт, вот его в case и вставляйте.
    Ответ написан