1

(0 ответов, оставленных в Problems)

Добрый день! Подскажите, пожалуйста, как написать ДП.
Нужно посчитать количество двоичных деревьев, где каждая вершина имеет 0 или 2 потомка, с заданными количеством вершин (N) и высотой (H).

2

(1 ответов, оставленных в Problems)

http://en.wikipedia.org/wiki/Four_color_theorem
http://ru.wikipedia.org/wiki/%D0%9F%D1% … 0%BE%D0%BA

3

(1 ответов, оставленных в Problems)

1) S - (V1+V2)*T
2) max(x, max(y, z))
3) периметр --- a + b + sqrt(a*a + b*b), площадь --- a*b/2.
4) a = max(x, max(y, z)), b = min(x, min(y, z)), c = x + y + z - a - b;
     x = b, y = c, z = a.

4

(3 ответов, оставленных в Problems)

Простой перебор.

5

(4 ответов, оставленных в Problems)

А код можно увидеть где-нибудь? И почему хуже по времени?

6

(4 ответов, оставленных в Problems)

есть задача - http://acm.timus.ru/problem.aspx?space=1&num=1005
сдал ее перебором подмножеств, но слышал о более оптимальном решении динамикой.
кто-нибудь может рассказать подробнее, как? спасибо.

7

(2 ответов, оставленных в Problems)

А каков результат? WA?
Вобще, тут простой теорвер.

8

(4 ответов, оставленных в Problems)

Сдал только что - перебирал все центры и бежал в две стороны - и если нашли несовпадение, то уменьшаем количество разрешенных замен на 1 (и так пока это количество > 0), походу дела наращиваем ответ. Пробежки таких делать надо две - одну для случая палиндромов нечетной длины, одну - для четной.

реализация на всякий пожарный:

#include <iostream>
#include <string>

using namespace std;

string s;
int n, k;

int main()
{
  cin >> n >> k;
  cin >> s;
  
  int cnt = 0;
  
  for (int c = 0; c < n; c++) {
    int i = c, j = c, allowed = k;
    while (i >= 0 && j < n && (s[i] == s[j] || allowed > 0)) {
      if (s[i] != s[j])
    --allowed;
      --i, ++j, ++cnt;
    }
  }
  
  for (int c = 0; c < n; c++) {
    int i = c, j = c + 1, allowed = k;
    while (i >= 0 && j < n && (s[i] == s[j] || allowed > 0)) {
      if (s[i] != s[j])
    --allowed;
      --i, ++j, ++cnt;
    }
  }
 
  cout << cnt << "\n";
}

9

(4 ответов, оставленных в Problems)

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

WA4 (

#include <cstdio>
#include <memory.h>

const int maxl = 1001;

char s[maxl][maxl];
int n, m, u[maxl][maxl];
int xl, yl, xr, yr;

int dx[8] = {-1, 0, 1, 0, -1, -1, 1, 1};
int dy[8] = {0, 1, 0, -1, -1, 1, 1, -1};
int di[4] = {-1, 0, 1, 0};
int dj[4] = {0, 1, 0, -1};

void walk(int x, int y)
{
  if (x < 0 || y < 0 || x >= n || y >= m)
    return;
  if (u[x][y])
    return;
  u[x][y] = 1;
  if (x < xl && y < yl)
    xl = x, yl = y;
  if (x > xr && y > yr)
    xr = x, yr = y;
  for (int i = 0; i < 8; i++)
    walk(x + dx[i], y + dy[i]);
}

int main()
{
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++)
    scanf("%s", s[i]);
  
  memset(u, 0, sizeof(u));
  
  bool anychanged = true;
  
  while (anychanged) {
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        if (s[i][j] == 'X' && !u[i][j]) {
      xl = i, xr = i;
          yl = j, yr = j;
    
      walk(i, j);
    
      for (int x = xl; x <= xr; x++)
        for (int y = yl; y <= yr; y++)
          s[y][x] = 'X', u[y][x] = 1;
        }
    
    anychanged = false;
    
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
    if (s[i][j] == '.') {
      int c = 0;
      for (int k = 0; k < 4; k++)
        if (i + di[k] >= 0 && j + dj[k] >= 0 && i + di[k] < n && j + dj[k] < m && s[i + di[k]][j + dj[k]] == 'X')
          ++c;
      if (c >= 2)
        s[i][j] = 'X', anychanged = true;
    }
  }
  
  int c = 0; 
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      c += (s[i][j] == 'X');
      
  printf("%d\n", c);
  return 0;
}

10

(4 ответов, оставленных в Problems)

Ага, если каждый раз смотреть, изменилось ли что-то и пробегать по полю, пока что-то меняется (заполняются новые клетки), то получается TL6

11

(4 ответов, оставленных в Problems)

Мне кажется, что в таком случае TL будет. Может быть есть более адекватное решение?

12

(4 ответов, оставленных в Problems)

WA5. Мое решение - пробегаю несколько раз по полю и заменяю незанятые клетки с числом соседей >= 2 на занятые.
Подскажите, пожалуйста, что может быть не так.

#include <cstdio>

const int maxl = 1001;

char s[maxl][maxl];
int n, m;

int di[4] = {-1, 0, 1, 0};
int dj[4] = {0, 1, 0, -1};

int main()
{
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++)
    scanf("%s", s[i]);
  for (int c = 0; c < 10; c++) {
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
    int c = 0;
    for (int k = 0; k < 4; k++)
      if (i + di[k] >= 0 && i + di[k] < n && j + dj[k] >= 0 && j + dj[k] < m && s[i + di[k]][j + dj[k]] == 'X')
        ++c;
    if (c >= 2)
      s[i][j] = 'X';
      }
  }
  int c = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (s[i][j] == 'X')
    ++c;
  printf("%d\n", c);
  return 0;
}

13

(2 ответов, оставленных в Problems)

Была такая задача на ленинградской областной олимпиаде - 2006

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

Во входном файле - отсортированная хронологически последовательность игр (описание игры имеет вид "WINNER-LOSER", где WINNER  и LOOSER - 3х-символьные идентификаторы команд).
В выходной файл необходимо вывести максимальное количество матчей в искомой цепочке, а затем и саму цепочку.

Пример входного файла:

5
FRA-ITA
GER-ITA
ITA-GER
ITA-LUX
RUS-ITA

Пример выходного файла:

3
RUS-ITA-GER-ITA

Вот мое решение (вроде бы вполне логичное, но валится на 6м тесте).
Подскажите, пожалуйста, что не так.

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>

using namespace std;

map <string, string> p;
map <string, int> d;
map <string, int>::iterator it;
string game;
int n;

int main()
{
  freopen("paradox.in", "rt", stdin);
  freopen("paradox.out", "wt", stdout);
  
  cin >> n;
  
  for (int i = 0; i < n; i++) {
    cin >> game;
    string s1 = game.substr(0, 3);
    string s2 = game.substr(4, 3);
    if (d[s2] + 1 > d[s1]) {
      d[s1] = d[s2] + 1;
      p[s1] = s2;
    }
  }
  
  string max_s = "";
  for (it = d.begin(); it != d.end(); it++)
    if (it->second > d[max_s])
      max_s = it->first;
      
  cout << d[max_s] << "\n";
  
  string s = max_s;
  for (int i = 0; i < d[max_s]; i++) {
    cout << s << "-";
    s = p[s];
  }
  
  cout << s << "\n";
  
  return 0;
}

14

(0 ответов, оставленных в Algo)

Добрый день! Подскажите, пожалуйста, где можно найти реализации построения диаграммы Вороного (C++)
за n^4 и за n*log(n).

15

(5 ответов, оставленных в Problems)

Спасибо всем!

16

(5 ответов, оставленных в Problems)

Помогите, пожалуйста, с задачей.
В треугольной сетке записаны числа следующим образом:

7
4 8
2 5 9
1 3 6 10

(a[1][1] = 1, a[1][2] = 2, a[2][1] = 3, и т.д.).

Необходимо по числу найти координаты в таком массиве. Можно ли это сделать чем-нибудь кроме перебора ?

17

(11 ответов, оставленных в Problems)

Решал динамикой, зааксептил smile