Мегаобучалка Главная | О нас | Обратная связь


Сложение беззнаковых длинных целых



2019-11-13 470 Обсуждений (0)
Сложение беззнаковых длинных целых 0.00 из 5.00 0 оценок




Чтение и вывод чисел в такой модели реализуется через строковый тип и в дополнительном описании не нуждается. Рассмотрим сложение двух неотрицательных чисел, каждое из которых сохранено в виде последовательности цифр.

Рис. 40. Поразрядное суммирование

Очевидно, при поразрядном суммированиичисел, которое начинается с конца строки, каждый разряд результата определяется по сумме трёх величин – переноса и соответствующих разрядов операндов. В разряд записывается остаток от деления этой суммы на 10, а переносом в следующий разряд идёт частное от деления нацело этой суммы на 10.

Рассмотрим задачу, иллюстрирующую применение такого подхода

Задача №215.  Длинные A+B

Найти сумму чисел A и B

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

В двух строках записаны числа Aи B, не превышающие 101000

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

Одно число – сумма A и B.

Решение

#include <iostream>

using namespace std;

int main(){

string a, b, c = "";

cin >> a >> b;

int lena = a.length()-1, lenb = b.length()-1,

     maxl = max(lena, lenb), carry = 0, op1, op2;

for(int i=0;i<=maxl;i++){

     op1 = i<=lena ? a[lena-i]-'0' : 0; 

     op2 = i<=lenb ? b[lenb-i]-'0' : 0;

     c = char((op1 + op2 + carry) % 10 + '0') + c;

     carry = (op1 + op2 + carry) / 10;

}

if(carry) c = char(carry + '0') + c;

cout << c;

}

Задача №216.  2^N (acmp.ru)

Необходимо вычислить значение 2n.

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

В единственной строке входного файла INPUT.TXT записано натуральное число n (0 < n < 1000).

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

В единственную строку выходного файла OUTPUT.TXT нужно вывести значение 2n.

Примеры

INPUT.TXT OUTPUT.TXT
1 3 8
2 10 1024
3 72 4722366482869645213696

Решение

Воспользуемся моделью представления «число=строка». Данное решение можно использовать для любого KN, при K≤9

#include <fstream>

#include <algorithm>            //описаниеreverse

#define BASE 2

using namespace std;

int main(){      

ifstream cin("input.txt");

ofstream cout("output.txt");

string ans="1", tmp;

int power,len, carry, expr,last;

cin >> power;

for(int i=1;i<=power;i++){

   tmp=ans;

   len=tmp.length();

   ans.clear();

   carry=0;

   for(intj=0;j<len;j++){  //каждый раз умножаем столбиком

       expr = (tmp[j]-'0')*BASE + carry;

       last = expr%10;          //последняяцифра

       carry = expr/10;         //перенос

       ans.push_back('0'+last);

   }

   if(carry)ans.push_back('0'+carry); //последний перенос

}

reverse(ans.begin(),ans.end());  //переворачиваем строку

cout << ans;

}

В строке ans хранится в символьной форме результат последнего умножения на BASE. Строка tmpявляется промежуточной и используется для временного хранения результата перед возведением в следующую степень.

Задача №217.  Длинный факториал

Требуется вычислить факториал целого числа N. Факториал обозначают как N! и вычисляют по формуле:

N! = 1 * 2 * 3 * … * (N-1) * N, причем 0! = 1.

Так же допустимо рекуррентное соотношение: N! = (N-1)! * N

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

В единственной строке записано одно целое неотрицательное число N (N < 1000).

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

Вывести одно целое число — значение N!

Пример

Ввод Вывод
1 6 720
2 17 355687428096000

Решение

#include <iostream>

using namespace std;

string mult(string x, int y){ //полудлинное умножение через строку

int carry = 0, t;

string result = "";

for (int i = x.size() - 1; i >= 0; i--){

    t = int(x[i] - '0')*y + carry;

   carry = t/10;

   result = char(t%10 + '0')+result;

}

while(carry){         //в разряде переноса остались цифры

   result = char(carry%10 + '0') + result;

   carry /= 10;

}

return result;

}

 

int main(){

int n;

string str = "1";

cin >> n;

for(int i = 2; i <= n; i++) str = mult(str, i);

cout << str << endl;

}

ВАЖНО: Одним из преимуществ данной модели представления длинных чисел является простота операций деления

Задача №218.  Очень длинное число

Учитель математики Сергей Иванович хочет проверить, какой остаток дает число 19202122…979899 (подряд записаны двузначные числа от 19 до 99) при делении на 31, 32, 33 и 34. Сергей Иванович подозревает, что число делится без остатка на все указанные делители. Помогите ему проверить, прав ли он.

Подсказка: признак делимости по сумме цифр как для чисел 3 и 32=9 в случае 33 и 34 не применим.

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

YES если Сергей Иванович прав, NO– если он ошибается.

Решение

Сохраним число Сергея Ивановича в строковый поток stringstreamst, а затем будем его посимвольно считывать. Воспользуемся модификацией деления методом «уголка».

 1920212223...99│ 81

-162│ 23...

300

 -243

57 и т.д.

Проиллюстрируем это на примере табличного процессора

Рис. 41. Решение задачи "Очень длинное число" в табличном процессоре

Если последний остаток в итоге окажется нулевым, значит Сергей Иванович прав.

#include <iostream>

#include <sstream>

using namespace std;

int main(){

string s;

string streamst(s);  // связываем поток st со строкой s

for(int i = 19; i <= 99; i++) st << i;//записываем число в поток

char t;

int temp=0;

for (int i = 1; i <= 3; i++){

     st >> t;

     (temp *= 10) += t - '0';

}

while (st >> t){  

((temp %= 81) *= 10) += t - '0';

cout << (temp % 3 ? "NO" : "YES");

}

В итоге Сергей Иванович окажется прав J

 

19.2 Модель 10^n

Представление числа напоминает представление многочлена, только вместо x в соответствующей степени имеем основание β в нужной степени. Как известно, многочлен a0 + a1x + a2x2 + … + anxn удобно представлять в виде массива, элементы которого представляют коэффициенты ai, а индекс i — определяет соответствующую степень x. Длинное число хранится аналогично, осталось определиться с выбором основания β.

Например, то же самое число 123456789 можно представить в десятитысячной (β = 104) системе счисления следующим образом:

12345678910 = 1*(104)2 + 2345*(104)1 + 6789*(104)0

Представляя число 123456789 в десятитысячной системе счисления, мы получаем сразу два преимущества:

1. сокращаем количество потребляемой памяти, так как вместо массива из 9 чисел нам достаточно хранить массив из 3 чисел (1, 2345 и 6789);

2. значительно уменьшаем время выполнения стандартных операций над длинными числами, поскольку за раз обрабатываем 4 разряда числа. В общем, компьютер одинаково быстро складывает одноразрядные и 32-разрядные числа, поэтому этим следует воспользоваться.

 

Задача №219.  Сумма произведений (acmp.ru)

Требуется вычислить сумму произведений цифр каждого N-значного числа. При этом следует учесть, что если в числе встречается цифра 0, то произведение его цифр равно нулю. Для N=3 искомая сумма представлена следующим рядом:

S = 1*0*0 + 1*0*1 + 1*0*2 + … + 9*9*8 + 9*9*9 = 91125

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

В единственной строке записано натуральное число N (N < 1000).

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

В единственную строку нужно вывести одно целое число — сумму произведений всех N-значных чисел.

Примеры

Ввод Вывод
1 1 45
2 3 91125
3 5 184528125

Решение

Легко заметить, что требуемые числа Snобразуют геометрическую прогрессию с шагом 45. В самом деле, если S1=45, то



аналогично для S3 и т.д.

#include<cstdio>

#define SIZE 400                     //ячеек в массиве

#defineBASE 1000000             //основание системы счисления

intn, i, a[SIZE]={45,};         //a[0]=45,остальныенули

int main(){

scanf("%d",&n);

for(;--n;){                 //вычисление 45^n

   for(i=0; i<SIZE; i++) a[i] *= 45;

   for(i=0; i<SIZE-1; i++){

       a[i+1] += a[i] / BASE;

       a[i] %= BASE;

   }

}

for(i=SIZE; !a[--i];); //вывод ячеек длинногочисла

printf("%d",a[i]);           //первая ненулевая как есть

for(;i--;) printf("%.6d",a[i]); //остальные с нулями спереди

}

 



2019-11-13 470 Обсуждений (0)
Сложение беззнаковых длинных целых 0.00 из 5.00 0 оценок









Обсуждение в статье: Сложение беззнаковых длинных целых

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение...
Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (470)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.007 сек.)