Задать вопрос
  • Экспорт файла SolidWorks для дальнейшего парсинга?

    wataru
    @wataru Куратор тега C++
    Я бы сделал так, прочитал файл и распарсил строчки AXIS2_PLACEMENT_3D, DIRECTION, CARTESIAN_POINT и CIRCLE. Можно поддерживать 4 разных мапа с ключами - номер строки, и данными оттуда. Что-то вроде map, map и map.

    При парсинге не надо никаких регулярок - просто разбиваете строку на токены по пробелам, первый - ключ ("#20"), второй должен быть "=", а третий - это тип строки. если он "CIRCLE" и т.д., то берете соответствуюие 1-3 токена в данные (можно float получить через функцию stof(). Для CIRCLE у вас одна строка - ключ (5-ый токен) и float - радиус (6-ой токен). Для Axis выделяете 3 cтроки - ключа. Для Direction и Cartesian_point вы выделяете 3 float.

    Потом проходитесь по всем CIRCLE, берете AXIS c нужным ключем, оттуда берете 3 строки c ключами для Cartesian Point и двух осей. Хотя оси, наверно, можно и игнорировать вообще. Потом в map-е для точки берете точку с нужным ключем. И вот у вас отверстие описывается радиусом, тройкой координат центра и двумя тройками координат осей. Оси, возможно, можно игнорировать. Все эти данные складывайте в новый класс. которые кладите в свой set. Оно автоматически дубликаты считать не будет. в конце его size() - это количество отверстий. И можно их все координаты вывести.
  • Экспорт файла SolidWorks для дальнейшего парсинга?

    wataru
    @wataru Куратор тега C++
    #357 = CIRCLE ( 'NONE', #49, 20.00000000000000355 ) ;


    А что написано в строке #49?

    Возьмите все 4 строки CIRCLE для одного отверстия и все 4 строки, на которые они ссылаются. Наверно, там будут отдельно записаны центры окружностей.

    Тогда стоит парсить все строчки CIRCLE и все строчки вида того, на что они ссылаются. Потом из них собирать тройки (координаты, радиус) и вот эти вот уникальные выдавать в ответ.
  • Экспорт файла SolidWorks для дальнейшего парсинга?

    wataru
    @wataru Куратор тега C++
    Artem Kirsov, Вы на весь файл смотрите. Может это и не отверстие.

    А вообще, можете реверс-инженирингом занятся. Подвигайте одно отверстие, если можете и смотрите, что в файле меняется.
  • Экспорт файла SolidWorks для дальнейшего парсинга?

    wataru
    @wataru Куратор тега C++
    Artem Kirsov, Ну структура там, так или иначе - как у всех 3d моделей. Полигоны/треугольники в пространстве. Или набор точек с координатами. а потом набор индексов, описывающих грани. Или набор граней заданных координатами точек.

    А вот как дырки искать - это отдельная очень сложная задача. В топологическом смысле? Вот сколько на этой картинке отверстий у объектов?

    Ее, наверно. можно даже решить, если у вас отверстия все вот такие - цилиндрическе в плоской модели. Но там все равно будет куча крайних случаев и исключений.
  • Экспорт файла SolidWorks для дальнейшего парсинга?

    wataru
    @wataru Куратор тега C++
    После парсинга нужно получить количество отверстий, их диаметр и расположение относительно друг друга или краев.
    Собственно алгоритм этого парсинга у вас уже есть?
  • Что за странная запись в С++?

    wataru
    @wataru Куратор тега C++
    Вова, ну просто забыли уже ненужную спецификацию удалить, наверно. Оно ничего не делает, смысла не добавляет.
  • Что за странная запись в С++?

    wataru
    @wataru Куратор тега C++
    Может, там было какое-то наследование. Может, раньше функция возвращала какого-то наследника Process, и вот так вызывался именно метод у предка.
  • Задания с CodeForces. Вариант решения есть, но не подходит для всех тестов. Может неправильно понял реализацию решения?

    wataru
    @wataru Куратор тега C++
    Alexandroppolus, Да, целочисленное. Да, это решение. Я лишь предложил более простое в понимании O(1) решение без аккуратного разбора случаев.
  • Задания с CodeForces. Вариант решения есть, но не подходит для всех тестов. Может неправильно понял реализацию решения?

    wataru
    @wataru Куратор тега C++
    stioann, Alexandroppolus, можно над случаями особо не думать, а просто перебрать до 0-1 шагов +3, 0-2 шагов -2 вложенными циклами, потом, если оставшийся путь отрицателен и делится на 2, или положителен и делится на 3, брать оставшееся количество ходов. Из всех вариантов выбираем мнинимальный.
  • Как подступиться? Нужна ли равномерная сетка ВЫЧМАТ?

    wataru
    @wataru Куратор тега Математика
    P1(x) - это полином первой степени?
  • Как сделать, что бы скрипт искал только фиксированное количество слагаемых?

    wataru
    @wataru Куратор тега Алгоритмы
    Canp, У вас очевидно проблема XY. Вы что-то придумали как вашу исходную задачу решать, свели ее к этому и ищите решение вот этой другой задачи. А она решений не имеет. Если вам порядок важен, всех вариантов просто тупо слишком много.
  • Как сделать, что бы скрипт искал только фиксированное количество слагаемых?

    wataru
    @wataru Куратор тега Алгоритмы
    Canp, Вы вообще представляете, сколько их там этих сочетаний? 7*10^51. Будет считать до тепловой смерти вселенной. Ваш исходный алгоритм, вообще-то тоже.

    У вас, я так понял, задача другая. Набрать разбить число на слагаемые от 1 до 7.

    Можно хоть и 6 вложенными циклами подсчитать (число 7-ок от 0 до 227//7. Число 6-ок от 0 до (227-7*num7)//6, Число 5-ок от 0 до сколько там влезает в оставшуюся часть числа. И т.д. Число 2 циклом,а число единиц - сколько осталось. Потом через тот же itertools.permutations генерируйте все варианты перемешать набор из num7 7-ок, num6 6-рок и т.д. Можно выходить из цикла если слагаемых слишком много, или если оставшехся чисел не хватит набрать слагаемые. Ну или короче рекурсией.

    import itertools
    
    def Gen(s, k, m, cur): # разбить S на K слагаемых от 1 до M
      if m == 1:
        if s != k: return
        new_list = list(cur)
        new_list.extend([1]*k)
        yield from set(itertools.permutations(new_list))
        #yield new_list # если порядок не важен
        return
      can_fit = min(s//m, k, (s-k)//(m-1))
      need_take = max(0, s-k*(m-1))
      new_list = list(cur)
      new_list.extend([m]*need_take)
      for i in range(need_take, can_fit+1):
        yield from Gen(s-m*i, k-i, m-1, new_list)
        new_list.append(m)
    
    print(Gen(227, 52, 7, []))


    Только там даже без перестановок 360 тысяч решений, и это умножается на какое-то офигенно большое число, ибо 52 слагаемых можно тасовать кучей способов. Там только одно из решений [5]*19+[4]*33 можно перетасовать 52!/19!/33! ~= 7*10^13 способами. Вы только его одно будете годами тасовать.
  • Что означает T()?

    wataru
    @wataru Куратор тега C++
    rPman, Это да, но вот int x{}; синициализирует 0. Или можно в функцию передать int().
  • Что означает T()?

    wataru
    @wataru Куратор тега C++
    У всех встроенных типов конструктор по умолчанию есть. Дает обычно 0.
  • Почему мой код не проходит по времени?

    wataru
    @wataru Куратор тега C++
    leean, Ну поэтапно же все познается. Формулуkol+= m/j-(n-1)/j то понял? Дальше разбиваем на 2 отдельные суммы. Одну с m, другую с n-1.

    Дальше, слагаемые с j до корня считаем просто тупо циклом. А оставшиеся слагаемые группируем. Это тот же прием, что и в самом начале сделали. Вместо счета суммы чисел, считаем, а сколько раз каждое число в сумме участвует.

    И я там накосячил, надо же "сколько раз число в сумме" домножить на само число. Что-то вроде должно быть
    kol += (m/j) +j*(m/j- m/(j+1)) ;
  • Почему мой код не проходит по времени?

    wataru
    @wataru Куратор тега C++
    leean, Если числа до 10^9, то наверно надо за корень делать.
  • Почему мой код не проходит по времени?

    wataru
    @wataru Куратор тега C++
    leean, А вообще, я был не прав. Можно и до корня сократить же.

    Рассмотрим сумму floor(m/i) для i до корня ее просто подсчитаем. Для оставшихся слагаемых, когда i >= корня, будем считать сколько раз каждое слагаемое всречается. при i >= sqrt(m), j = m/i <= sqrt(m). Вот переберем это j. Для скольких i можно получить floor(m/i) = j? j <= m/i < j+1, m/(j+1) < i <= m/j, отсюда i = floor(m/(j+1))+1 .. floor(m/j). В итоге, надо подсчитать сумму floor(m/j) - floor(m/(j+1)).

    в итоге будет что-то вроде

    for(long long j=1;j<sqrt(m);++j){
            kol += 2*(m/j) - m/(j+1) ;
    }
    for(long long j=1;j<sqrt(n-1);++j){
            kol -= 2*((n-1)/j) - (n-1)/(j+1) ;
    }


    Возможно накосячил и где то +-1 надо. Особенно аккуратно проверьте, что работает, когда m и/или n - полный квадрат.
  • Почему мой код не проходит по времени?

    wataru
    @wataru Куратор тега C++
    leean, Вообще, да, можно сократить до m/2 потому что все итерации после дадут ровно 1 всегда и их можно в одно действие подсчитать. И как, все еще не проходит? Какие там вообще ограничения в задаче на размер чисел и time limit?