Модераторы: 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   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Интересные и занимательные задачи по программированию | Следующая тема »


 




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


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

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