Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
2 / 2 / 0
Регистрация: 03.05.2020
Сообщений: 202

Сообщающиеся сосуды

04.08.2021, 05:19. Показов 5261. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сообщающиеся сосуды
Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что если взять два одинаковых сосуда, соединённых тонкой трубкой на уровне основания, то уровень жидкости при любом её количестве также будет одинаковым для обоих сосудов.

Способ убедиться в правильности утверждения Витя избрал довольно оригинальный. Он взял аквариум с основанием длиной N и шириной 1, очень высокими стенками и поставил N–1 перегородок параллельно узкой боковой стенке аквариума, тем самым разделив аквариум на N одинаковых отсеков. Каждая перегородка имеет ширину 1 и очень большую высоту. Толщиной перегородки можно пренебречь. В каждой из перегородок есть точечное отверстие на высоте Hi, диаметром которого также можно пренебречь. После всех этих приготовлений Витя медленно наливает в первый отсек (между стенкой и первой перегородкой) C литров воды. В часть аквариума размером 1×1×1 вмещается ровно один литр воды. Так как стенки и перегородки в аквариуме были очень высокими, то через край вода не переливалась. После установления стационарного состояния он замерил уровень жидкости в каждом из N сосудов.

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

Рассмотрим подробно случай N=3. Пусть сначала H1<H2. Как только жидкость в первом отсеке достигнет уровня первого отверстия, вода станет поступать во второй отсек до тех пор, пока уровни в обоих отсеках не сравняются (или уровень воды в первом отсеке окажется равным H1, тогда во втором отсеке он будет на уровне C–H1). Далее уровень жидкости в первых двух частях будет увеличиваться равномерно (или не будет меняться). Как только вода достигнет второго отверстия, вся она будет поступать в третий отсек, опять же до тех пор, пока уровни жидкости во всех трёх частях не сравняются или вода в первых двух отсеках достигнет уровня H2. После этого, если воды оказалось достаточно, весь аквариум будет заполняться равномерно.

Пусть теперь H1>H2. Как только жидкость в первом отсеке достигнет уровня первого отверстия, вся вода станет поступать во второй отсек. Если после этого уровень во втором отсеке сравняется с уровнем второго отверстия, то вода станет выливаться в третий до тех пор, пока высоты жидкостей во втором и третьем отсеках не станут равными. Далее уровень воды в них будет равномерно увеличиваться, пока не достигнет первого отверстия. После этого весь аквариум будет заполняться равномерно.

Входные данные

В первой строке записаны целые N и C (1≤N≤100000, 0≤C≤2⋅109). В следующих N–1 строках содержится по одному целому числу Hi (0≤Hi≤2⋅109), обозначающему высоту отверстия в i-й перегородке.

Выходные данные

Выведите N чисел, каждое на новой строке, с точностью до шести знаков после десятичной точки — уровень жидкости в 1,2,...,N отсеке соответственно.

Примеры
Ввод
4 4
3
2
1
Вывод
3.00000000000000000000
1.00000000000000000000
0.00000000000000000000
0.00000000000000000000
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.08.2021, 05:19
Ответы с готовыми решениями:

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

Олимпиадная задача. Сообщающиеся сосуды
Пожалуйста, решите задачку 2013 года. Имеется система резервуаров в форме параллелепипедов, сообщающихся тонкими трубочками (их...

Cообщающиеся сосуды
Добрый день, есть такая задача, без понятий как её решать, писать можно как угодно, потом переделаю под свое условие(но если что то надо...

8
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6166 / 2859 / 1042
Регистрация: 01.06.2021
Сообщений: 10,461
04.08.2021, 09:34
dmitrii2000, 2⋅109 это 2⋅10^9 ?
0
8 / 7 / 1
Регистрация: 08.04.2021
Сообщений: 151
07.08.2021, 16:36
Цитата Сообщение от Royal_X Посмотреть сообщение
2⋅109 это 2⋅10^9 ?
Да.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6166 / 2859 / 1042
Регистрация: 01.06.2021
Сообщений: 10,461
07.08.2021, 16:44
alimaaa, в этой теме выложено решение для python Сообщающиеся сосуды, исследуйте алгоритм и напишите на с++
0
2 / 2 / 0
Регистрация: 03.05.2020
Сообщений: 202
08.08.2021, 08:05  [ТС]
Скиньте код пожалуйста
0
8 / 7 / 1
Регистрация: 08.04.2021
Сообщений: 151
08.08.2021, 14:25
dmitrii2000, меняешь сообщающиеся сосуды на прямоугольники или на выборы в сша?
0
2 / 2 / 0
Регистрация: 03.05.2020
Сообщений: 202
08.08.2021, 14:48  [ТС]
Меняю на прямоугольнки
0
8 / 7 / 1
Регистрация: 08.04.2021
Сообщений: 151
08.08.2021, 16:02
Лучший ответ Сообщение было отмечено dmitrii2000 как решение

Решение

Окей вот сосуды:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#define NN 1000000
#define eps 1e-7
 
int n;
double C;
double a[NN], p[NN];
int h[NN];
int s, t, i, j;
double l, r;
 
 
 
double
get_h (void)
{
  assert (s < t);
  return a[h[s]];
}
 
int
pop_h (void)
{
  assert (s < t);
  return h[s++];
}
 
void
push_h (int x)
{
  while (s < t && a[h[t - 1]] < a[x])
    t--;
  h[t++] = x;
}
 
int
main (int argc, char *argv[])
{
  double ev, ev1, ev2;
  int x;
  scanf ("%d%lf", &n, &C);
  for (i = 0; i < n - 1; i++)
    scanf ("%lf", &a[i]);
 
  for (i = 0; i < n; i++)
    p[i] = 0;
  s = 0; t = 0;
  i = 0; j = 1;
  l = C; r = 0;
  push_h (0);
//   printf('\n');
 
  while (j < n && i < j && l > a[j - 1] + eps)
    {
      ev1 = (l - r) * (j - i) / (j - i + 1);
      if (s < t)
    {
      ev2 = (l - get_h ()) * (j - i);
      ev = (ev1 < ev2) ? ev1 : ev2;
    }
      else
    ev = ev1;
      l -= ev / (j - i);
      r += ev;
      assert (l + eps > r);
      if (fabs (l - r) < eps)
    {
      push_h (j);
      j++;
      r = 0;
    }
      if (fabs (l - get_h ()) < eps)
    {
      x = pop_h ();
      for (; i <= x; i++){
        p[i] = l;
      }
      i = x + 1;
    }
      if ((i == j) || (l < a[j - 1] + eps))
    {
      for (; i < j; i++){
        p[i] = l;
      }
      l = r;
      r = 0;
      i = j;
      push_h (j);
      j++;
    }
    }
  for (; i < j; i++){
    p[i] = l;
  }
 
  for (i = 0; i < n; i++)
    printf ("%0.20lf\n", p[i]);
 
  return 0;
}
Добавлено через 48 минут
dmitrii2000, Ауу ты здесь?
4
0 / 0 / 0
Регистрация: 16.03.2020
Сообщений: 18
15.08.2021, 12:25
alimaaa, привет, вот прямоугольники если надо:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
 
using namespace std;
 
#define ll long long
 
vector<ll>func(ll n,vector<vector<ll>>&arr)
{
    vector<vector<ll>>v(n,vector<ll>(2));
 
    for(ll i = 0;i<n;++i){
 
        v[i][0] = arr[i][0];
 
        v[i][1] = i;
    }
 
    sort(v.begin(),v.end());
 
    set<ll>st;
    vector<ll>ans(n);
 
    vector<ll>temp;
 
    for(ll i = 0;i<n;++i){
 
        ll t = v[i][1];
 
        if(i && v[i][0] != v[i-1][0]){
 
            for(ll j = 0;j<temp.size();++j)st.insert(temp[j]);
 
            temp.clear();
        }
 
        temp.push_back(t);
 
        auto it = st.lower_bound(t);
 
        if(it == st.begin())continue;
 
        --it;
 
        ans[t] = (*it) + 1;
 
    }
 
    return ans;
 
}
 
 
int main()
{
    ll n;
    cin >> n;
 
    vector<vector<ll>>v(n,vector<ll>(2));
    for(ll i = 0;i<n;++i)cin >> v[i][1] >> v[i][0];
 
    vector<ll>l = func(n,v);
 
    reverse(v.begin(),v.end());
 
    vector<ll>r = func(n,v);
 
    for(ll i = 0;i<n;++i)r[i] = n-r[i]+1;
 
    reverse(r.begin(),r.end());
    reverse(v.begin(),v.end());
 
    vector<ll>pref(n);
 
    pref[0] = v[0][1];
 
    for(ll i = 1;i<n;++i)pref[i] = pref[i-1] + v[i][1];
 
    ll ma = 0;
 
    for(ll i = 0;i<n;++i){
 
        ll to_left = (!l[i] ? pref[i] : (pref[i] - pref[l[i]-1]));
 
        ll to_right = ((r[i] == n+1) ? (pref.back() - pref[i]) : (pref[r[i]-2] - pref[i]) );
 
        ma = max(ma,(to_left+to_right)*v[i][0]);
 
    }
 
    cout << ma;
 
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.08.2021, 12:25
Помогаю со студенческими работами здесь

Сообщающиеся сосуды
Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что если взять два...

Сообщающиеся сосуды
Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что если взять два...

Сообщающиеся сосуды
Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что если взять два...

Сообщающиеся сосуды
Сообщающиеся сосуды Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что...

Сообщающиеся сосуды
Сообщающиеся сосуды Сегодня на уроке физики рассказывали удивительные вещи. Придя домой, Витя решил проверить слова учителя о том, что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru