Форум программистов, компьютерный форум CyberForum.ru

Задача про водопровод - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
25.12.2011, 22:05     Задача про водопровод #1
Город Восточный постоянно страдает от недостатка воды. Для устранения этой проблемы была построена новая водопроводная труба. Строительство трубы началось с обоих концов одновременно, и спустя некоторое время половины соединились. Ну, почти. Первая половина трубы заканчивалась в точке (x1, y1), а вторая - в точке (x2, y2).

К сожалению, осталось лишь несколько отрезков трубы различной длины. Более того, из-за специфики местной технологии трубы могут быть проложены только в направлении с севера на юг или с востока на запад и соединяются, образуя или прямую, или угол 90 градусов. Требуется, зная длины отрезков труб L1, L2, ..., LK и количество отрезков каждой длины C1, C2, ..., CK, сконструировать трубу, соединяющую две заданные точки, или определить, что это невозможно.

Ограничения: 1 <= K <= 4, 1 <= x1, y1, x2, y2, Li <= 1000, 1 <= Ci <= 10, все числа целые, время 3 с.
Ввод из файла wpipe.in. В первой строке находятся числа x1, y1, x2, y2, K, затем 2K чисел: L1, L2, ..., LK, C1, C2, ..., CK.
Вывод в файл wpipe.out. Вывести одно число - минимальное количество нужных отрезков труб или -1, если соединение невозможно.
Примеры
Ввод 1 Ввод 2
5 5 5 6 1 2 10 20 10 60 50 2 70 30 2 2
Вывод 1 Вывод 2
-1 4
моя попытка решить:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <fstream>
using namespace std;
void main()
{ifstream wpipein; ofstream wpipeout;
int c[4],l[4]; int x1,y1,x2,y2,i,j,s=0,t=0,m;
int k;
wpipein.open("wpipein.txt"); wpipeout.open("wpipeout.txt");
wpipein>>x1>>y1>>x2>>y2>>k;
for (i=0; i<k; i++)
wpipein>>c[i]>>l[i];
for (i=0;i<k; i++)
for (j=0;j<k;j++)
{if ((abs(x1-x2)==s+c[i]*l[i])&&(abs(y1-y2)==t+c[j]*l[j])&&(c[k]>=c[i]+c[j]))
{s=c[i]*l[i]; t=c[j]*l[j];
if ((abs(x1-x2)%l[k]==0)&&(abs(y1-y2)%l[k]==0))
{m=abs(x1-x2)/l[k]+abs(y1-y2)/l[k];
if (m<=c[k]) wpipeout<<m; else wpipeout<<-1;
}}}}
скажите я вообще правильно рассуждаю?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.12.2011, 22:05     Задача про водопровод
Посмотрите здесь:

C++ Задача про слона 0о
Задача про скобки C++
C++ Задача про кузнечиков
C++ Задача про год
C++ Задача про биты
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
26.12.2011, 06:23     Задача про водопровод #2
Цитата Сообщение от crewww Посмотреть сообщение
скажите я вообще правильно рассуждаю?
нет.
Сначало ошибки в коде (см комментарии):
Цитата Сообщение от crewww Посмотреть сообщение
{if ((abs(x1-x2)==s+c[i]*l[i])&&(abs(y1-y2)==t+c[j]*l[j])&&(c[k]>=c[i]+c[j]))// здесь обращение к несуществующему элементу c[k]
Цитата Сообщение от crewww Посмотреть сообщение
if ((abs(x1-x2)%l[k]==0)&&(abs(y1-y2)%l[k]==0))// здесь обращение к несуществующему элементу l[k]
и в двух строчках ниже тоже самое.
Теперь переформулирую задачу:
Есть два расстояния: abs(x1-x2) и abs(y1-y2)
и есть K труб длиннами: L1, L2, ..., LK и их количество C1, C2, ..., CK
Задача: можно ли набрать из заданного набора труб два расстояния - abs(x1-x2) и abs(y1-y2). Если можно, то вывести результат, в котором количество труб используемых в заданном наборе будет минимальным.
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
26.12.2011, 12:07  [ТС]     Задача про водопровод #3
то есть должно выполняться условие:
abs(x1-x2)+abs(y1-y2)==c[i]*l[i]+c[j]*l[j];
а как мы определим когда количество труб будет минимальным?
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
26.12.2011, 15:58     Задача про водопровод #4
Цитата Сообщение от crewww Посмотреть сообщение
то есть должно выполняться условие:
abs(x1-x2)+abs(y1-y2)==c[i]*l[i]+c[j]*l[j];
не обязательно. И скорее всего чаще нет, чем да.
Должно выполняться следующее условие:
abs(x1-x2)= l[0]*x0 + l[1]*x1 + ... + l[k-1]*xk-1
abs(y1-y2)= l[0]*y0 + l[1]*y1 + ... + l[k-1]*yk-1
xi и yi лежат в диапазоне от 0 до c[i]
Причем для любого i должно соблюдаться условие xi+yi<=c[i]
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
27.12.2011, 09:37  [ТС]     Задача про водопровод #5
Цитата Сообщение от valeriikozlov Посмотреть сообщение
не обязательно. И скорее всего чаще нет, чем да.
Должно выполняться следующее условие:
abs(x1-x2)= l[0]*x0 + l[1]*x1 + ... + l[k-1]*xk-1
abs(y1-y2)= l[0]*y0 + l[1]*y1 + ... + l[k-1]*yk-1
xi и yi лежат в диапазоне от 0 до c[i]
Причем для любого i должно соблюдаться условие xi+yi<=c[i]
извините за тупые вопросы, но объясните как можно это все на c++ реализовать
несовсем понимаю откуда эти x[i], y[i] брать да еще связать с c[i]
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
27.12.2011, 10:09     Задача про водопровод #6
Цитата Сообщение от crewww Посмотреть сообщение
несовсем понимаю откуда эти x[i], y[i] брать да еще связать с c[i]
Есть например 3 трубы длинной 2
и 2 трубы длинной 17
Нужно из них набрать 2 отрезка: один длинной 19, второй длинной 4.
Такие отрезки можно набрать:
Первый (длинной 19) набираем так: одна труба длинной 17 и одна труба длинной 2
Второй (длинной 4) набираем так: две трубы длинной 2

Но с таким набором труб нельзя например набрать:
- два отрезка длинной 19 и 6 (не хватит труб длинной 2)
- два отрезка длинной 19 и 5 (из заданных труб невозможно набрать длинну 5)

Цитата Сообщение от crewww Посмотреть сообщение
но объясните как можно это все на c++ реализовать
Попробуйте сначало понять смысл задачи, только потом попробуйте ее реализовать. Если не получится помогу.
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
27.12.2011, 13:45  [ТС]     Задача про водопровод #7
Цитата Сообщение от valeriikozlov Посмотреть сообщение
Есть например 3 трубы длинной 2
и 2 трубы длинной 17
Нужно из них набрать 2 отрезка: один длинной 19, второй длинной 4.
Такие отрезки можно набрать:
Первый (длинной 19) набираем так: одна труба длинной 17 и одна труба длинной 2
Второй (длинной 4) набираем так: две трубы длинной 2

Но с таким набором труб нельзя например набрать:
- два отрезка длинной 19 и 6 (не хватит труб длинной 2)
- два отрезка длинной 19 и 5 (из заданных труб невозможно набрать длинну 5)


Попробуйте сначало понять смысл задачи, только потом попробуйте ее реализовать. Если не получится помогу.
то есть x[i], y[i] это "нужные нам трубы"?

Добавлено через 2 часа 39 минут
Цитата Сообщение от valeriikozlov Посмотреть сообщение
Есть например 3 трубы длинной 2
и 2 трубы длинной 17
Нужно из них набрать 2 отрезка: один длинной 19, второй длинной 4.
Такие отрезки можно набрать:
Первый (длинной 19) набираем так: одна труба длинной 17 и одна труба длинной 2
Второй (длинной 4) набираем так: две трубы длинной 2

Но с таким набором труб нельзя например набрать:
- два отрезка длинной 19 и 6 (не хватит труб длинной 2)
- два отрезка длинной 19 и 5 (из заданных труб невозможно набрать длинну 5)


Попробуйте сначало понять смысл задачи, только потом попробуйте ее реализовать. Если не получится помогу.
отрезком вы называете то что нужно найти получается?
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
27.12.2011, 14:18     Задача про водопровод #8
Цитата Сообщение от crewww Посмотреть сообщение
отрезком вы называете то что нужно найти получается?
отрезками я называю: abs(x1-x2) и abs(y1-y2)
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
27.12.2011, 23:08  [ТС]     Задача про водопровод #9
как нужно учесть условие минимальности количества нужных отрезков труб

Добавлено через 1 час 29 минут
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
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;
 
int main()
{int j,i,x1,y1,x2,y2,k,s;
int c[4], l[4],m[100],n[100];
    ifstream wpipein;
ofstream wpipeout;
wpipein.open("wpipein.txt");
wpipeout.open("wpipeout.txt");
wpipein>>x1>>y1>>x2>>y2>>k;
for (i=0; i<k;i++)
wpipein>>l[i]>>c[i];
for (i=0; i<k; i++)
for (j=0; j<k; j++)
{m[i]=abs(x1-x2)/l[k-1];
    if (abs(x1-x2)%l[k-1]!=0 && m[i]>=c[i]-m[i])
     if (abs(y1-y2)%l[k-1]!=0 && n[j]>=c[j]-n[j])
    wpipeout<<-1;
 
}
for (i=0; i<k; i++)
for (j=0; j<k; j++)
{
    if (abs(x1-x2>=m[i]*l[i])&&(abs(y1-y2)>=n[j]*l[j]))
    if (abs(y1-y2)+abs(x1-x2)<=c[i]) s=m[i]+n[i];
    if (s>c[i]) {s=c[i]; wpipeout<<s;} else wpipeout<<-1;
}
wpipein.close();
wpipeout.close();
cin.get();
cin.get();
    return 0;
}
еще одна попытка
почему то проблема с выводом, то есть он неправильно выводит..
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 05:43     Задача про водопровод #10
Давайте попробуем рекурсией:
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
#include <iostream>
#include <fstream>
using namespace std;
int c[4], l[4],m[100],n[100]; 
int j,i,x1,y1,x2,y2,k,s, res=-1;
void rec(int sum, int fl, int pred, int col)
{
    
    if(fl==1)
    {
        if(sum==y1)
        {
            if(res==-1)
                res=col;
            else
            {
                if(res>col)
                    res=col;
            }
            return;
        }
        if(sum>y1)
            return;
        if(pred==k)
            return;
        int i;
        for(i=0; i<=c[pred]; i++)
        {
 
            rec(sum+i*l[pred], fl, pred+1, col+i);
        }
    }
    else
    {
        if(sum==x1)
        {
            rec(0, 1, 0, col);
        }
        if(sum>x1)
            return;
        if(sum<x1)
        {
            if(pred==k)
                return;
            int i, tmp=c[pred];
            for(i=0; i<=tmp; i++)
            {
                c[pred]=tmp-i;
                rec(sum+i*l[pred], fl, pred+1, col+i);
                c[pred]=tmp;
            }
        }
    }
 
}
int main()
{
    ifstream wpipein;
    ofstream wpipeout;
    wpipein.open("wpipein.txt");
    wpipeout.open("wpipeout.txt");
    wpipein>>x1>>y1>>x2>>y2>>k;
    for (i=0; i<k;i++)
        wpipein>>l[i]>>c[i];
    x1=abs(x1-x2); y1=abs(y1-y2);
    rec(0, 0, 0, 0);
    wpipeout<<res;
    wpipein.close();
    wpipeout.close();
    return 0;
}
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
28.12.2011, 09:48  [ТС]     Задача про водопровод #11
Цитата Сообщение от valeriikozlov Посмотреть сообщение
Давайте попробуем рекурсией:
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
#include <iostream>
#include <fstream>
using namespace std;
int c[4], l[4],m[100],n[100]; 
int j,i,x1,y1,x2,y2,k,s, res=-1;
void rec(int sum, int fl, int pred, int col)
{
    
    if(fl==1)
    {
        if(sum==y1)
        {
            if(res==-1)
                res=col;
            else
            {
                if(res>col)
                    res=col;
            }
            return;
        }
        if(sum>y1)
            return;
        if(pred==k)
            return;
        int i;
        for(i=0; i<=c[pred]; i++)
        {
 
            rec(sum+i*l[pred], fl, pred+1, col+i);
        }
    }
    else
    {
        if(sum==x1)
        {
            rec(0, 1, 0, col);
        }
        if(sum>x1)
            return;
        if(sum<x1)
        {
            if(pred==k)
                return;
            int i, tmp=c[pred];
            for(i=0; i<=tmp; i++)
            {
                c[pred]=tmp-i;
                rec(sum+i*l[pred], fl, pred+1, col+i);
                c[pred]=tmp;
            }
        }
    }
 
}
int main()
{
    ifstream wpipein;
    ofstream wpipeout;
    wpipein.open("wpipein.txt");
    wpipeout.open("wpipeout.txt");
    wpipein>>x1>>y1>>x2>>y2>>k;
    for (i=0; i<k;i++)
        wpipein>>l[i]>>c[i];
    x1=abs(x1-x2); y1=abs(y1-y2);
    rec(0, 0, 0, 0);
    wpipeout<<res;
    wpipein.close();
    wpipeout.close();
    return 0;
}
в некоторых случаях программа работает к сожалению неверно(
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 11:55     Задача про водопровод #12
Цитата Сообщение от crewww Посмотреть сообщение
в некоторых случаях программа работает к сожалению неверно(
эти случаи описать можете? Или можете дать ссылку на тестирующую систему?

Добавлено через 22 минуты
Вот так попробуйте:
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
#include <iostream>
#include <fstream>
using namespace std;
int c[4], l[4],m[100],n[100]; 
int j,i,x1,y1,x2,y2,k,s, res=-1;
void rec(int sum, int fl, int pred, int col)
{
        
        if(fl==1)
        {
                if(sum==y1)
                {
                        if(res==-1)
                                res=col;
                        else
                        {
                                if(res>col)
                                        res=col;
                        }
                        return;
                }
                if(pred==k)
                        return;
                int i;
                for(i=0; i<=c[pred]; i++)
                {
 
                        rec(sum+i*l[pred], fl, pred+1, col+i);
                        if(i!=0)
                            rec(sum-i*l[pred], fl, pred+1, col+i);
                }
        }
        else
        {
                if(sum==x1)
                {
                        rec(0, 1, 0, col);
                }
                else
                {
                        if(pred==k)
                                return;
                        int i, tmp=c[pred];
                        for(i=0; i<=tmp; i++)
                        {
                                c[pred]=tmp-i;
                                rec(sum+i*l[pred], fl, pred+1, col+i);
                                if(i!=0)
                                    rec(sum-i*l[pred], fl, pred+1, col+i);
                                c[pred]=tmp;
                        }
                }
        }
 
}
int main()
{
    ifstream wpipein;
        ofstream wpipeout;
        wpipein.open("wpipein.txt");
        wpipeout.open("wpipeout.txt");
        wpipein>>x1>>y1>>x2>>y2>>k;
        for (i=0; i<k;i++)
            wpipein>>l[i];
        for (i=0; i<k;i++)
            wpipein>>c[i];
        x1=abs(x1-x2); y1=abs(y1-y2);
        rec(0, 0, 0, 0);
        wpipeout<<res;
        wpipein.close();
        wpipeout.close();
        return 0;
}
Если не пройдет, и если есть возможность, то дайте ссылку на тестирующую систему.
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
28.12.2011, 13:43  [ТС]     Задача про водопровод #13
Цитата Сообщение от valeriikozlov Посмотреть сообщение
эти случаи описать можете? Или можете дать ссылку на тестирующую систему?

Добавлено через 22 минуты
Вот так попробуйте:
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
#include <iostream>
#include <fstream>
using namespace std;
int c[4], l[4],m[100],n[100]; 
int j,i,x1,y1,x2,y2,k,s, res=-1;
void rec(int sum, int fl, int pred, int col)
{
        
        if(fl==1)
        {
                if(sum==y1)
                {
                        if(res==-1)
                                res=col;
                        else
                        {
                                if(res>col)
                                        res=col;
                        }
                        return;
                }
                if(pred==k)
                        return;
                int i;
                for(i=0; i<=c[pred]; i++)
                {
 
                        rec(sum+i*l[pred], fl, pred+1, col+i);
                        if(i!=0)
                            rec(sum-i*l[pred], fl, pred+1, col+i);
                }
        }
        else
        {
                if(sum==x1)
                {
                        rec(0, 1, 0, col);
                }
                else
                {
                        if(pred==k)
                                return;
                        int i, tmp=c[pred];
                        for(i=0; i<=tmp; i++)
                        {
                                c[pred]=tmp-i;
                                rec(sum+i*l[pred], fl, pred+1, col+i);
                                if(i!=0)
                                    rec(sum-i*l[pred], fl, pred+1, col+i);
                                c[pred]=tmp;
                        }
                }
        }
 
}
int main()
{
    ifstream wpipein;
        ofstream wpipeout;
        wpipein.open("wpipein.txt");
        wpipeout.open("wpipeout.txt");
        wpipein>>x1>>y1>>x2>>y2>>k;
        for (i=0; i<k;i++)
            wpipein>>l[i];
        for (i=0; i<k;i++)
            wpipein>>c[i];
        x1=abs(x1-x2); y1=abs(y1-y2);
        rec(0, 0, 0, 0);
        wpipeout<<res;
        wpipein.close();
        wpipeout.close();
        return 0;
}
Если не пройдет, и если есть возможность, то дайте ссылку на тестирующую систему.
http://ipc.susu.ac.ru/workplace-4.html

Добавлено через 9 минут
Цитата Сообщение от crewww Посмотреть сообщение
правда не в этой системе дело
я сам вручную ввожу также как в примере то есть 5 5 5 6 1 2 10
и должно выводить -1 а она то выводит
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 13:47     Задача про водопровод #14
у меня последний вариант получил AC.
Только нужно в коде поменять название файлов ввода вывода, на те которые используются в тестирующей системе.
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
28.12.2011, 17:45  [ТС]     Задача про водопровод #15
спасибо большое теперь действительно все работает

Добавлено через 3 часа 48 минут
извините а вы не могли бы подробно разобрать процедуру rec
а именно : какие аргументы она принимает за что они отвечают, ну и в общем принцип весь что откуда... преподаватель очень строго все будет проверять сказал
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 19:07     Задача про водопровод #16
Цитата Сообщение от crewww Посмотреть сообщение
извините а вы не могли бы подробно разобрать процедуру rec
могу. но только если вы сами полностью поняли условие задачи (иначе это будет объяснение в никуда).
Сможете объяснить почему в тесте:
20 10 60 50 2 70 30 2 2
ответ 4
?
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
28.12.2011, 19:15  [ТС]     Задача про водопровод #17
Цитата Сообщение от valeriikozlov Посмотреть сообщение
могу. но только если вы сами полностью поняли условие задачи (иначе это будет объяснение в никуда).
Сможете объяснить почему в тесте:
20 10 60 50 2 70 30 2 2
ответ 4
?
потому что из данных двух наборов мы можем собрать 4 трубы тем добравшись из точки (x1,y1) до точки (x2,y2)
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 19:24     Задача про водопровод #18
Цитата Сообщение от crewww Посмотреть сообщение
потому что из данных двух наборов мы можем собрать 4 трубы тем добравшись из точки (x1,y1) до точки (x2,y2)
ответ на 5.
а какие трубы и как используются?
Чтобы понять как решается задача, самое первое - нужно понять условие. Этот тест и есть понимание условия. Я могу сейчас написать комментарии к функции rec(), но 100% что вы не поймете смысл этой функции, пока не поймете самого задания.
crewww
30 / 1 / 1
Регистрация: 28.10.2010
Сообщений: 102
28.12.2011, 19:39  [ТС]     Задача про водопровод #19
Цитата Сообщение от valeriikozlov Посмотреть сообщение
ответ на 5.
а какие трубы и как используются?
Чтобы понять как решается задача, самое первое - нужно понять условие. Этот тест и есть понимание условия. Я могу сейчас написать комментарии к функции rec(), но 100% что вы не поймете смысл этой функции, пока не поймете самого задания.
трубы собираются из заданных нам отрезков соответствующих длин
то есть мы берем самую длинную трубу и примеряемся так скажем (строим горизонтальную составляющую), затем также примеряемся по вертикали, и если мы добрались до (x2,y2) то значит можно построить такой водопровод. количество труб в будем не больше c суммых всех отрезков если я правильно понимаю
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.12.2011, 19:56     Задача про водопровод
Еще ссылки по теме:

Задача водопровод C++
C++ задача про графы

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

Или воспользуйтесь поиском по форуму:
valeriikozlov
Эксперт C++
 Аватар для valeriikozlov
4660 / 2486 / 321
Регистрация: 18.08.2009
Сообщений: 4,550
28.12.2011, 19:56     Задача про водопровод #20
Цитата Сообщение от crewww Посмотреть сообщение
трубы собираются из заданных нам отрезков соответствующих длин
то есть мы берем самую длинную трубу и примеряемся так скажем (строим горизонтальную составляющую), затем также примеряемся по вертикали, и если мы добрались до (x2,y2) то значит можно построить такой водопровод. количество труб в будем не больше c суммых всех отрезков если я правильно понимаю
ладно, все понятно, вот комментарии:
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
void rec(int sum, int fl, int pred, int col)// sum - сумма уже набранной длины (для первого или для второго отрезка), 
//fl==0 если набираем длину для первого отрезка, fl==1 если набираем длину для второго отрезка
// индекс труб, которые перебираем на данном вызове rec()
// col - количество труб, которые уже использовали для достижения текущего значения
{
        
        if(fl==1)// если набираем вторую длину
        {
                if(sum==y1)// если вторую длину набрали
                {
                        if(res==-1)// если результата еще не было
                                res=col;// то результат равен col
                        else// если результат уже был
                        {
                                if(res>col)// если полученное значение меньше записанного результата
                                        res=col;// то результат равен этому значению
                        }
                        return;// возврат из функции
                }
                if(pred==k)// если достигли конца массива струбами
                        return;// возврат из функции
                int i;
                for(i=0; i<=c[pred]; i++)// перебираем трубы с текущим индексом (pred)
                {
 
                        rec(sum+i*l[pred], fl, pred+1, col+i);// то прибавляем их длину
                                                if(i!=0)
                                                        rec(sum-i*l[pred], fl, pred+1, col+i);// то убавляем их длину
                }
        }
        else// если набираем первую длину
        {
                if(sum==x1)// если первую длину набрали
                {
                        rec(0, 1, 0, col);// начинаем набирать вторую длину
                }
                else
                {
                        if(pred==k)// если достигли конца массива струбами
                                return;// возврат из функции
                        int i, tmp=c[pred];
                        for(i=0; i<=tmp; i++)// перебираем трубы с текущим индексом (pred)
                        {
                                c[pred]=tmp-i;// убавляем значение задействованных труб
                                rec(sum+i*l[pred], fl, pred+1, col+i);// то прибавляем их длину
                                                                if(i!=0)
                                                                        rec(sum-i*l[pred], fl, pred+1, col+i);/ то убавляем их длину
                                c[pred]=tmp;// в конце восстанавливаем значение
                        }
                }
        }
 
}
Yandex
Объявления
28.12.2011, 19:56     Задача про водопровод
Ответ Создать тему
Опции темы

Текущее время: 03:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru