rukia
							
								Интересующийся 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 «  : 10-12-2008 14:45 »   | 
								
								 | 
							  
							 
							доброе время суток! есть задание посчитать факториал 100 000! =(  вот я делаю так: #include "stdafx.h" #include <iostream> #include <fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //чтобы посчитать факториал от х надо совершить х-1 умножений const int n=35660;// количество разрядов в числе( для факториала 10000! n=35660,дла100000!=456574) int r=1; int c[n];//теперь инициализируем начальный массив. c[n-1]=1;for(int i=n-2;i>=0;i--){c[i]=0;}//в младшем разряде сначала 1, а остальные пока нули int z=0;//вспомогательная int x=10000;//x это то число, факториал которого нужен. for(int i=0; i<x-1;i++) {r+=1; for(int k=n-1;k>=0;k--)//поразрядно с конца {   int a=c[k]*r+z;   c[k]=(c[k]*r+z)%10;   z=a/10; } } ofstream rukia("Fucktorial.txt",ios::out); if(!rukia) { 	cerr<<"Oblom!"; } for(int i=0;i<n;i++) rukia<<c[i]; return 0; }//снизойди с ледяных небе это то, что приходит в голову сразу. оно считает корректно, скажем, 2!, 10!, 15! весьма быстро считает и 10 000! но когда дело доходит до 100 000!, то виндоус начинает просить прощения и ничего не делает...о.0 я пробовала заменять тип элемента массива на short int, исходя из соображений, что меньше памяти выделять. тогда виндоус не просит прощения и делает фигню.. то есть где-то часа через пол выводит на сто страниц нулей..=( подскажите, пожалуйста, что надо делать? и почему так? =) может, кто-то уже решал подобную задачу)  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 10-12-2008 14:53 »   | 
								
								 | 
							  
							 
							А чего удивительного? чем больше аргумент факториала, тем больше на конце нулей. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							rukia
							
								Интересующийся 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 10-12-2008 15:29 »   | 
								
								 | 
							  
							 
							знаю.. но он выводит т о л ь к о нули... к тому же время работы около получаса, мы даже успели пообедать за то время и чуть про него не забыть. а надо не более 7-8 минут=) алгоритм, чтоли не подходящий?) 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 10-12-2008 15:33 »   | 
								
								 | 
							  
							 
							Вот тут: правильно я понимаю, что r может достигать 100000? Тогда, думается, скоро понадобится большой перенос в старшие разряды. После каждого умножения - иначе будет переполняться.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							rukia
							
								Интересующийся 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 10-12-2008 15:45 »   | 
								
								 | 
							  
							 
							аа..) спасибо! то есть я погорячилась здесь   и переполняется "int а"? значит ее тоже надо представить массивом?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #5 : 10-12-2008 15:49 »   | 
								
								 | 
							  
							 
							Тогда лучше, наверное, развести первый множитель и результат умножения по разным массивам - так будет нагляднее. И после умножения одного разряда потребуется вложенный цикл для переноса (вместо просто вспомогательной z=a/10). 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 10-12-2008 15:51 от Вад »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Crystal
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #6 : 10-12-2008 16:20 »   | 
								
								 | 
							  
							 
							Здравствуйте! у меня аналогичная проблема. Необходимо вычислить факториал 100000. Написанный мною код правильно считает 20!, 30!.....10000!. а вот  на 100000 выдает ошибку, подскажите пожалуйста как это исправить и правильно ли я делаю??? #include <iostream> #include <math.h> #include <fstream> using namespace std;
  void main() {int mas[7], i;//массив хранит колич. знаков в значении факториала mas[6]=1; for(i=0;i<6;i++) { 	mas[i]=0; }
  int m; for(m=2;m<=10;m++)//в данном случае вычисляем факториал 10 {    for(i=6;i>=0;i--) 	{ 		mas[i]=mas[i]*m; 	} for(i=6;i>=0;i--) { 	if(mas[i]>9) 		{ 			float f=(float)mas[i]/10; 			mas[i]=(mas[i]%10); 			mas[i-1]=mas[i-1]+floor(f); 		} } }
  ofstream xxx("Faktorial.txt",ios::out); if(!xxx) { 	cerr<<"Error!!!"; } for(i=0;i<7;i++) xxx<<mas[i]; 	 }
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 10-12-2008 19:11 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #7 : 10-12-2008 17:23 »   | 
								
								 | 
							  
							 
							Crystal, ровно тот же самый код и та же ошибка - см. выше. Где вы его берёте?    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Crystal
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #8 : 10-12-2008 17:47 »   | 
								
								 | 
							  
							 
							то есть перенос нужно сразу осуществлять не только в соседний разряд, но и в старшие после каждого умножения...правильно я поняла?  ?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #9 : 10-12-2008 17:59 »   | 
								
								 | 
							  
							 
							По моим прикидкам, отложенный перенос может переполниться. Экспериментально не проверял    Надо у rukia спросить, что получилось    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Crystal
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #10 : 10-12-2008 18:09 »   | 
								
								 | 
							  
							 
							извините, но что вы имеете в виду под фразой "отложенный перенос"? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #11 : 10-12-2008 19:55 »   | 
								
								 | 
							  
							 
							Я имел в виду конструкцию с z = a / 10 и переносом этого значения в следующий разряд, суммирования его с произведением там, и так далее.  Однако, и на старуху бывает проруха. Попробовал. Дело оказалось не в том, что я думал. В общем, выкладываю поправленный и немного оптимизированный по времени код (отрабатывает у меня примерно раза в 1,5-2 быстрее): // Factor.cpp : Defines the entry point for the console application. //
  #include "stdafx.h" #include <iostream> #include <fstream> using namespace std;
  int _tmain(int argc, _TCHAR* argv[]) {     //чтобы посчитать факториал от х надо совершить х-1 умножений     const int n=500000;// количество разрядов в числе( для факториала 10000! n=35660,дла100000!=456574)
      // выделяем память под массив     int* c = new int[n];     //теперь инициализируем начальный массив.         for (int i = 0; i < n; ++i)         c[i] = 0;     c[0]=1;     int z=0; //вспомогательная     int max = 0;     int x=100000;//x это то число, факториал которого нужен.     for(int i=2; i <= x ; ++i)     {         for(int k = 0; k <= max; ++k)//поразрядно с младшего         {             z = c[k]*i + z;             c[k] = z % 10;             z /= 10;             if (z && k == max)                 ++max;         }     }
      ofstream rukia("Fucktorial.txt",ios::out);     if(!rukia)     { 	    cerr<<"Oblom!";     }
      for(int i=max; i >=0 ; --i)         rukia<<c[i];          // удаляем массив     delete[] c;          return 0; }
  Со статическим массивом на 500 тыщ элементов мне стек порвало   P.S. Аккурат 456574 байта в файле.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 10-12-2008 20:10 от Вад »
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							rukia
							
								Интересующийся 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #12 : 12-12-2008 02:37 »   | 
								
								 | 
							  
							 
							спасибо,Вад! те первые-неумные-коды похожи были,видимо, потому, что все чайники думают похоже=) у меня есть еще один вопрос..,. код с динамическим массивом работает за ~20 мин на 2ядерном компутере. нам дали ограничение в 10 минут. то есть надо оптимизировать. Уменьшение памяти, выделяемой на элемент(то есть  short int c[..], char c[..]почему-то только делает хуже о.0 странно, почему)  наиболее логичным выглядит вариант уменьшить количество эл-тов массива. тоесть, посчитать мегачисло не в 10ной, а в ну.. например 256чной системе счисления. а потом отдельно перевести в 10ную. с переносом не отложенным,а хорошим. ох.. может, есть еще способы? =)
  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #13 : 12-12-2008 05:50 »   | 
								
								 | 
							  
							 
							Можно считать "% 1000" или даже "% 10000" в одной ячейке - при умножении на 100000 должно хватить int для переноса (советую проверить    ). Только один нюанс - вывод в поток надо сделать аккуратнее - чтобы на каждый разряд, кроме старшего, выводилось ровно 3 или 4 знака соответственно. Умножений станет намного меньше, так что резко возрастёт скорость. Но, вообще, этот код у меня на Core2Duo отрабатывал минут за 8.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Sla
							
						 | 
						
							
								  | 
								
									
									 « Ответ #14 : 12-12-2008 07:24 »   | 
								
								 | 
							  
							 
							я так понимаю, что результат хранится в строке В случае появления числа с нулями - запоминать нули, а при выводе их учитывать 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Мы все учились понемногу... Чему-нибудь и как-нибудь. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #15 : 12-12-2008 07:28 »   | 
								
								 | 
							  
							 
							Sla, можно, в принципе, и средствами iostream сманеврировать, заставив выводить нужное число символов и дополнять нулями. А можно, конечно, и нули выводить отдельно. Это уж на откуп топикстартеру    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Sla
							
						 | 
						
							
								  | 
								
									
									 « Ответ #16 : 12-12-2008 07:40 »   | 
								
								 | 
							  
							 
							а еще можно запоминать один ноль после каждого девятого умножения или 2 нуля после каждого десятого   Offtopic:  Вопрос: Как быстро умножить на 10 в процессоре который не имеет команд умножения?) Ответ: Умножить на 8 и дважды прибавить самое себя
 
 Поставлю в угол.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Мы все учились понемногу... Чему-нибудь и как-нибудь. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Вад
							
						 | 
						
							
								  | 
								
									
									 « Ответ #17 : 12-12-2008 08:12 »   | 
								
								 | 
							  
							 
							В случае появления числа с нулями - запоминать нули, а при выводе их учитывать А, я не так понял. Ты предлагал все младшие разряды до первого ненулевого сокращать? Тоже хорошая оптимизация получится на таких масштабах    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							rukia
							
								Интересующийся 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									«  Ответ #18 : 12-12-2008 22:36 »    | 
								
								 | 
							  
							 
							замечательно))))) сейчас на пробу сделала по "методу %100" и во время аццкого испытания на том компе,которы считал за 19-20 минут, посчиталось за 645 секунд! (ну.. в смысле, правильно посчиталось) Но, вообще, этот код у меня на Core2Duo отрабатывал минут за 8.  угум, ради инереса проверили    Core2Duo еще быстрее..   а еще можно запоминать один ноль после каждого девятого умножения или 2 нуля после каждого десятого 
  о, даа. по сути,я даже могу рассчтитать количество нулей вконце для факториала.. например для 500! так: 500\5=100; 100\5=20; 20\5=4; то есть noll=100+20+4=124, что совпадает с экспериментом. то есть,как только множитель r увеличивается на 5(на 2 он увеличивается тем более, а 2*5=10), то сразу +ноль к концу..и массив можно заполнять получается чтоли в 2 направления?    спасибо !    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	 |