Модераторы: Alx, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> "Трамвайные билеты", предполагается решение 
:(
    Опции темы
mr.Anderson
Дата 15.5.2006, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



Вот такая задачка есть.

Нужно найти в трамвайных билетах "счастливые". Это такие билеты, в которых сумма первых двух цифр равна сумме двух последних цифр (предполагается, что номер билета имеет четыре разряда). Как понятно, придется использовать массив. Элементы массива - от 1 до 9999, т.е. массив объявлен и заполнен вот так:
Код

const int arrSize=9999;
int array[arrSize];
//И заполнен вот так:
for(int x=0; x<arrSize; x++)
 array[x]=x+1;

Воть. Я бы хотел увидеть ваши решения. Я уже решил задачу, и мне хочется сравнить свое решение с вашим (свое пока не выкладываю, чтобы некуда было подглядывать smile ). 


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
maxim1000
Дата 15.5.2006, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



ну, например, так:
Код

int SumCount(int sum)
//считает, сколькими способами можно составить заданную сумму
//работает только для 0..18
{
  if(sum<=9)
    return sum+1;
  return 18-sum+1;
}
int LuckyCount()
//считает количество счастливых билетиков
{
  int count=0;
  for(int sum=0;sum<=18;++sum)
    count+=SumCount(sum);
  return count;
}


Добавлено @ 20:49 
Цитата(sim7 @  15.5.2006,  17:47 Найти цитируемый пост)
Как понятно, придется использовать массив

совсем необязательно smile  

Это сообщение отредактировал(а) maxim1000 - 15.5.2006, 20:49


--------------------
qqq
PM WWW   Вверх
mr.Anderson
Дата 17.5.2006, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



Гм... Интересно... Правда, я не совсем понял принцип работы функции SumCount в вашем примере...

Как и обещал, выложу свое решение (я работал с описанным выше массивом):
Код

//---------------------------------------------------------------------------
#include <iostream>

using std::cout;
using std::endl;

#include <conio>
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

void main(void)
{
 const int arrSize=9999;
 int array[arrSize];
 int count=0;

 for(int j=0; j<arrSize; ++j)
  array[j]=j+1;

 cout<<"Счастливые билеты: "<<endl;

 for(int i=0; i<arrSize; ++i)
 {
  int part1 = static_cast<int>(array[i]/1000); //разряд № 1
  int threeParts = array[i]-(static_cast<int>(array[i]/1000)*1000); //остальные три разряда
  int part2 = static_cast<int>(threeParts/100); //разряд № 2
  int twoParts = threeParts-(static_cast<int>(threeParts/100)*100); //оставшиеся два разряда
  int part3 = static_cast<int>(twoParts/10); //разряд № 3
  int part4 = twoParts-(static_cast<int>(twoParts/10)*10); //и последний разряд № 4

  if((part1+part2)==(part3+part4))
  {
   ++count;
   cout<<"array["<<i<<"] = "<<array[i]<<endl;
  }
 }

 cout<<"Количество счастливых билетов: "<<count<<endl<<endl<<"Жмите любую клавишу...";

 getch();
}
//---------------------------------------------------------------------------

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

Добавлено @ 19:42 
P.S. Пример, конечно, очень плох с точки зрения производительности, но в случае работы с указанным массивом, вроде, только так и можно...

maxim1000, а приведите пример не для 18, а для 9999. 


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
mr.Anderson
Дата 17.5.2006, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



И еще, maxim1000, включите плиз в ваш код функцию main. Не совсем понятен код в целом... И плиз поясните функцию SumCount. Мне кажется, для числа 9999 ее придется немного переделать, хотя я, честно говоря, не понимаю, как. 


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
maxim1000
Дата 17.5.2006, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



упс... неправильно понял задание...
я думал, что надо найти количество счастливых билетиков
впрочем, если подумать, то и его я не совсем правильно решил - при добавлении нужно ещё возводить сумму в квадрат
...
описание:
каждый счастливый билетик можно охарактеризовать суммой его первых двух цифр (она же - сумма других двух)
удобно (по крайней мере, это - один из способов) отдельно рассматривать каждую возможную сумму
сумма двух цифр может быть 0..18
теперь вопрос: какие могут быть билетики с заданной суммой первых/последних двух цифр?
достаточно перебрать все варианты первой пары цифр, а для каждой из них ещё и все варианты второй пары (тут появляется квадрат, который я забыл)
как перебирать варианты?
в случае с длиной номеров 4 эта задача вообще простая:
начинаем с такой пары, в которой первая цифра самая большая, а вторая - самая маленькая
для сумм 0..9 это будет пара x0 (x - сумма)
для сумм 10..18 - 9y (y=сумма-9)
следующую пару можно получить, отняв 1 от первой цифры и добавив её ко второй, останавливаться надо, когда переносить уже некуда - вторая цифра 9 или неоткуда - первая цифра 0

вот и получаем такую процедуру:

Код

bool Inc(char *digitpair)
{
  if(digitpair[0]=='0')
    return false;
  if(digitpair[1]=='9')
    return false;
  --digitpair[0];
  ++digitpair[1];
  return true;
}
void PrintAllLuckyNumbers()
{
  for(int sum=0;sum<=18;++sum)
  {
    char digits[5];
    if(sum<10)
    {
      digits[0]=digits[2]=sum+'0';
      digits[1]=digits[3]='0';
    }
    else
    {
      digits[0]=digits[2]='9';
      digits[1]=digits[3]=sum-9+'0';
    }
    digits[5]=0;//чтобы выводить удобно было
    do
    {
      do
      {
        cout<<digits<<"\n";
      } while(Inc(digits+2));
    } while(Inc(digits));
  }
}
 

Это сообщение отредактировал(а) maxim1000 - 17.5.2006, 20:19


--------------------
qqq
PM WWW   Вверх
nostromo
Дата 18.5.2006, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: нет
Всего: 10



Вариант решения на Smalltalk (не смог удержаться ;) )
Код

sumDigits := [:v |  (v \\ 10) + (v // 10) ].
isLuckyPair := [:x :y | (sumDigits value: x) = (sumDigits value: y)].
res := (0 to: 9999) select: [:n | isLuckyPair value:  (n // 100) value: (n \\ 100)].
res do: [:n | Transcript cr; show: n displayString].
 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
mr.Anderson
Дата 18.5.2006, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


iOS Lead Developer
****


Профиль
Группа: Участник Клуба
Сообщений: 3374
Регистрация: 20.12.2004
Где: далеко

Репутация: 1
Всего: 128



Я так и не понял, как же вы разбиваете число на разряды. Ну никак не могу въехать. Понятно, если число двузначное. А если четырех? И сделайте, я просил, для числа 9999, а не 18.

А про мой-то код что можете сказать?

Добавлено @ 16:14 
nostromo, мы тут про С++... Ваш код мне мало что говорит, поскольку я его не знаю. smile  


--------------------
user posted image

user posted image
PM MAIL ICQ Skype   Вверх
nostromo
Дата 18.5.2006, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: нет
Всего: 10



Ну ладно, вот вариант на C++.
Код

size_t sumDigits(size_t n)
{
    if ( n > 9999) 
        throw "Too big number!";
    return (n / 10) + (n % 10);
}

bool isLuckyPair(size_t x, size_t y)
{
    return sumDigits(x) == sumDigits(y);
}

int main()
{ 
  
  for (size_t i = 0; i < 99; ++i)
      for (size_t j = 0; j < 99; ++j)
        if (isLuckyPair(i,j))
            cout << (i + 100 * j) <<endl;
  return 0;
}


Добавлено @ 16:44 
Цитата

А про мой-то код что можете сказать?


В принципе, нормально.
Только два замечания: 
1. static_cast<int> не нужен. Результат деления целых чисел --- целое число.
2. С точки зрения алгоритма, я бы предпочел получать цифры цисла в цикле вида:
Код

int n = ...;
int digits[nnDigits];
int n1 = n;
for (int i =0 ; i< nnDigits; ++i,  n1 = n1 / 10)
{
  int nextDigit = n1 % 10;
  digits[i] = nextDigit;
}

 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
maxim1000
Дата 18.5.2006, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата(sim7 @  18.5.2006,  15:13 Найти цитируемый пост)
И сделайте, я просил, для числа 9999, а не 18

у меня нет функции проверки конкретного числа на "счастливость", у меня просто выводятся все счастливые четырёхзначные числа...
поэтому ни для какого конкретного числа таким образом не проверишь... 


--------------------
qqq
PM WWW   Вверх
nostromo
Дата 18.5.2006, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: нет
Всего: 10



Цитата

у меня просто выводятся все счастливые четырёхзначные числа...

Идея хорошая, но я бы реализовал примерно так:
Код

typedef std::vector<int> vector_i;

vector_i allNumbersWithDigitsSum(size_t sum)
{
    vector_i res;
    for(int i = std::max<int>(0, sum-9); i < std::min<int>(9, sum); ++i)
        res.push_back(10*i + (sum - i));
    return res;
}

int main()
{ 
  for (size_t i = 0; i < 18; ++i)
  {
      vector_i list = allNumbersWithDigitsSum(i);
      for (vector_i::iterator iter = list.begin(); iter != list.end(); ++iter)
          for (vector_i::iterator iter1 = list.begin(); iter1 != list.end(); ++iter1)
            std::cout << (*iter)*100+(*iter1) <<std::endl;
  }
  return 0;
}
  

Это сообщение отредактировал(а) nostromo - 18.5.2006, 17:15
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
666andrey666
Дата 28.5.2006, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 10.5.2006

Репутация: нет
Всего: нет



По-моему вот это решение неплохое для чисел от 1 до 9999!!!
Код

int a,b,c,d,m;
for (a=0;a<10;a++)
 for (b=0;b<10;b++)
  for (c=0;c<10;c++)
   for (d=0;d<10;d++)
    if (a+b==c+d) { m=1000*a+100*b+10*c+d; cout << m << " ";}
 
PM MAIL   Вверх
Akina
Дата 29.5.2006, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 2
Всего: 454



Цитата(666andrey666 @  28.5.2006,  21:21 Найти цитируемый пост)
По-моему вот это решение неплохое для чисел от 1 до 9999!!!

Плохое... как тебе выведется билет номер 0110? а просто 110... 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
nostromo
Дата 29.5.2006, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: нет
Всего: 10



Цитата(Akina @ 29.5.2006,  09:33)
Цитата(666andrey666 @  28.5.2006,  21:21 Найти цитируемый пост)
По-моему вот это решение неплохое для чисел от 1 до 9999!!!

Плохое... как тебе выведется билет номер 0110? а просто 110...

Мне кажется, что работать будет, 0110 или 110 --- какая разница? 
Но это решение действительно плохое тем, что негибкое (код сильно завязан на количестве цифр) и неэффективное (по сравнению с вариантом перебора только подходящих билетов). 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
Romikgy
Дата 29.5.2006, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 2
Всего: 146



Цитата(666andrey666 @  28.5.2006,  19:21 Найти цитируемый пост)
cout << m << " ";

printf("%04d\n",m);
smile 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
666andrey666
Дата 30.5.2006, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 10.5.2006

Репутация: нет
Всего: нет



Цитата

Плохое... как тебе выведется билет номер 0110? а просто 110...  


это устранить не тяжело!!!

 smile 


Цитата


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


во всяком случае для таких цифр я задачу решил и пашет она быстро!! я же ведь её решал не для всех случаев жизни!!!

 
PM MAIL   Вверх
nostromo
Дата 30.5.2006, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 23.3.2006

Репутация: нет
Всего: 10



Цитата

во всяком случае для таких цифр я задачу решил и пашет она быстро!! я же ведь её решал не для всех случаев жизни!!!

Пашет быстро по сравнению с загрузкой файла в Ворд? ;) 
Все относительно, и вообще, плоха та программа, которая не мечтает стать модулем в другой программе (мое мнение). 
--------------------
На пыльных тропинках далеких планет останутся наши следы.
PM MAIL   Вверх
ILAgent
Дата 12.6.2006, 00:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 1.3.2006

Репутация: нет
Всего: нет



Предлагаю вот такой вариант :

Код


struct PairDigs
{
    unsigned char d1,d2;
} ;

int GetNumbers(vector<int> &vNumbers)
{    
               vNumbers.clear();
    vector<PairDigs> vPairs;
    PairDigs digs;

    for(int i=0;i<=18;i++)
    {
        
                
        vPairs.clear();
        
        //ищем пары цифр, сумма которых i
        float fHalfSum=i/2;
        digs.d1=floor(fHalfSum);
        digs.d2=ceil(fHalfSum);

        for(;(digs.d1>=0)&&(digs.d2<=9);digs.d1--,digs.d2++)
        {
            vPairs.push_back(digs);
            if(digs.d1!=digs.d2)
            {
                PairDigs digs2;
                digs2.d1=digs.d2;
                digs2.d2=digs.d1;
                vPairs.push_back(digs2);
            }
        }
        
        //все комбинации из двух пар цифр
        for(int j=0;j<vPairs.size();j++)
            for(int k=0;k<vPairs.size();k++)
            {
            vNumbers.push_back(vPairs[j].d1+vPairs[j].d2*10+
                                                                                   vPairs[k].d1*100+vPairs[k].d2*1000);
            }

    }
                 return vNumbers.size();
}
  

Это сообщение отредактировал(а) ILAgent - 12.6.2006, 00:07
PM MAIL   Вверх
Oleg_Ci
Дата 20.8.2006, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Friend
**


Профиль
Группа: Участник
Сообщений: 485
Регистрация: 28.5.2006
Где: Новосиб.обл.

Репутация: нет
Всего: 30



Задача про трамвайные былеты давно решалась, но я её сумел решить и выложил своё решение. У меня маленькая программка получилась. Решал так как maxim1000 объяснял, а не перебором.
Код

#include <stdio.h>

void main()    
{    
    int kol = 0, begin, end;
    for ( int name=0; name<=18; name++  )
    {
        if ( name<10 ) { begin = 0; end = name; }
        else { begin = name-9; end = 9; }

        for ( int j = begin; j <= end; j++ )
            for ( int x = begin; x <= end; x++, kol++ )
                printf("%d %d %d %d\n", j, name-j, x, name-x );
    }
    printf("\n\n\nKol-vo biletov :  %d\n\n\n", kol );
    getchar();
}

PM MAIL   Вверх
Oleg_Ci
Дата 12.10.2006, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Friend
**


Профиль
Группа: Участник
Сообщений: 485
Регистрация: 28.5.2006
Где: Новосиб.обл.

Репутация: нет
Всего: 30



Ещё решение изобрелось smile 
Код

#include <stdio.h>

int main(int argc, char *argv[] )
{
    int count = 1, i;

    for ( i = 1; i<10000; i++ )
        if( i % 10 + i / 10 % 10 == i / 100 % 10 + i / 1000 )    
            printf("%2d%6d\n",count++, i );

    getchar();
    return 0;
}

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема »


 




[ Время генерации скрипта: 0.1694 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.