演算法設計與分析:第三章 分治 3.3二進位制大整數的乘法
/* 二進位制大整數的乘法: 請設計一個有效的演算法,可以進行兩個n 位二進位制大整數的乘法運算 設x = 3141, A = 31 B=41 y = 5327, C = 53,D=27 x*y = AC*2^n + (AD + BC)*2^(n/2) + BD = AC*2^n + ((A-B)*(D-C) + A*C + B*D)*2^n + BD //少算一次乘法 遞迴基:當只有一個元素的時候 下面實現的是十進位制大整數乘法 輸入: 3141 5327 10(必須確保位數為偶數位) 9 11 2(必須確保該十進位制數對應的二進位制數是位數相同的) 輸出: 16732107 99 731074749 */ /* 這裡其實沒有用到分治,因為需要分解數字,下次考慮到x,y均小於10的時候再計算 */ #include <stdio.h> #include <iostream> using namespace std; bool g_valid;//全部標記變數 int sign(int a)//獲取整數a的符號 { return a > 0 ? 1 : -1; } int myAbs(int a) { return a > 0 ? a : -1*a; } int digitCount(int a,int iBase) { int iTotalDigit = 0; do { a /= iBase;//獲取下一位 iTotalDigit++; }while(a); return iTotalDigit; } int getBack(int a,int iBase,int iTotalDigit)//iBase為基數 { if(a <= 0)//這裡必須確保a是正數 { g_valid = false; return -1; } /*只需要把後半段計算出來,然後用前半段去減。問題轉化為如何求出後半段。1234:必須知道總共位數/2,求一個整數的位數, 可以用它自己不斷和它本身減一去取與,很快可以求解。 設定一個計數器,當達到總位數一半的時候,停止計數,然後將陣列中儲存的從低位到高位的累加和輸出 */ int iCnt = 0; int iSum = 0; int iFactor = 1; do { iSum += iFactor*(a % iBase); iFactor *= iBase; a /= iBase; iCnt++; if(iCnt == iTotalDigit/2) { break; } }while(a); return iSum; } //返回iBase^iExp int myPow(int iBase,int iExp) { if(iExp == 1)//遞迴出口 { return iBase; } int iRet = myPow(iBase,iExp/2); iRet *= iRet; if(iExp % 2 == 1) { iRet *= iBase; } return iRet; } int multiply(int x,int y,int iBase) { //預處理符號 int iSign = sign(x) * sign(y); x = myAbs(x); y = myAbs(y); //魯棒性 int iTotalDigitX = digitCount(x,iBase); int iTotalDigitY = digitCount(y,iBase); // if(iTotalDigitX != iTotalDigitY) { g_valid = false; return -1; } //遞迴出口,如果都為1,返回乘積的符號 if(x == 1 && y == 1) { return iSign; } else { //計算每一個數的前半部分和後半部分 int iDivideNum = myPow(iBase,iTotalDigitX/2); int iBackX = getBack(x,iBase,iTotalDigitX); //靠計算錯了,例如5341計算出的是5300,還要除以100 int iFrontX = ( x - iBackX ) / iDivideNum; int iBackY = getBack(y,iBase,iTotalDigitY); int iFrontY = ( y - iBackY ) / iDivideNum; //計算每一部分乘積 int iM1 = iFrontX * iFrontY; int iM2 = iBackX * iBackY; int iM3 = (iFrontX - iBackX) * (iBackY - iFrontY) + iM1 + iM2; int iRet = iSign * ( iM1*myPow(iBase,iTotalDigitX) + iM3*myPow(iBase,iTotalDigitX/2) + iM2 ); return iRet; } } void process() { int x,y,iBase; while(EOF != scanf("%d %d %d",&x,&y,&iBase)) { g_valid = true; int iRet = multiply(x,y,iBase); if(g_valid) { printf("%d\n",iRet); } else { printf("您輸入的兩個整數%d %d的位數不一致,請檢查!\n",x,y); } } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }
相關推薦
演算法設計與分析:第三章 分治 3.3二進位制大整數的乘法
/* 二進位制大整數的乘法: 請設計一個有效的演算法,可以進行兩個n 位二進位制大整數的乘法運算 設x = 3141, A = 31 B=41 y = 5327, C = 53,D=27 x*y = AC*2^n + (AD + BC)*2^(n/2) + BD
演算法設計與分析基礎 第三章謎題
習題3.1 6.四格拼板 四格拼板是由4個1*1的正方形組成。下面是5種類型的四格拼板: 分別利用以下四格拼板,看看是否有可能在不重疊的情況下完全覆蓋一個8*8的棋盤。 a. 直線拼板 可以,長和寬能被8整除 b. 方形拼板
演算法設計與分析:第五章 回溯法 5.8流水作業車間排程
/* 流水作業車間排程: n個作業要在兩臺機器M1和M2組成的流水線上完成加工。每個作業加工的順序都是現在M1上加工,然後在 M2上加工。M1和M2加工作業i所需的時間分別為ai和bi。流水作業排程問題要求確定這n個作業的最優 加工順序,使得從第一個作業在機器M1上開始加工
演算法設計與分析:第四章 動態規劃 4.2TSP之貨郎擔問題
/* 如果對於任意數目的n個城市,分別用1~n編 號,則這個問題歸結為在有向帶權圖中,尋找一 條路徑最短的哈密爾頓迴路問題。 這裡,V表示城市頂點,(i,j) ∈E 表示城市之 間的距離,用鄰接矩陣C表示城市之間的距離。 思想: 1設d(i,V-{i})表示從頂點i出發
《演算法設計與分析》第三週作業
《演算法設計與分析》第三週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第三週作業 @[toc] 題目概要 思路 思路一 思路二 具體實
演算法設計與分析基礎 第五章謎題
習題5.1 11.Tromino謎題 Tromino是一個由棋盤上的三個1×1方塊組成的L型骨牌。我們的問題是,如何用Tromino覆蓋一個缺少了一個方塊的2n×2n棋盤。除了這個缺失的方塊,Tromino應該覆蓋棋盤上的所有方塊,Tromino可以任意轉向但不能有重疊。 為此問題
演算法設計與分析基礎 第四章謎題
習題4.1 1.擺渡的士兵 n個士兵組成的分隊必須越過一條又深又寬又沒有橋的河。他們注意到在岸旁有兩個12歲大的小男孩在玩划艇。然而船非常小,只能容納兩個男孩或一名士兵。怎樣才能讓士兵渡過河,並且留下兩個男孩操縱這條船?這條船要在岸與岸之間橫渡多少次? 解答:每次只能容納一名士兵,所以士
演算法設計與分析基礎 第六章謎題
習題6.1 9.數字填空 給定n個不同的整數以及一個包含n個空格的序列,每個空格之間事先給定有不等(>或<)符號,請設計一個演算法,將n個整數填入這n個空格中並滿足不等式約束。例如,數4,6,3,1,8可以填在這樣的5個空格中: 解答:將n個正整數從小到大排序,然後將數
演算法設計與分析基礎 第七章謎題
習題7.1 6. 祖先問題要求在一棵給定的n頂點二叉樹中,確定一個頂點u是否是頂點v的祖先。設計一個屬於O(n)的輸入增強演算法,使我們可以在常量時間內獲得樹的每一對頂點的足夠資訊,來對問題求解。 分析:一個頂點u是頂點v的祖先,當前僅當先序遍歷u在v的前面,並且後序遍歷u在v的後面。第
XSS的原理分析與解剖:第三章(技巧篇)**************未看*****************
第二章 != chrom 插入 是把 調用 bject innerhtml ats ??0×01 前言: 關於前兩節url: 第一章:http://www.freebuf.com/articles/web/40520.html 第二章:http://www.free
演算法設計與分析:第二章 遞迴 2.7多項式求值問題
/* 多項式求值問題: 有如下多項式: P (x)= An*x^n + An-1*x^(n-1) + ... +a1*x + a0 如果分別對每一項求職,需要n*(n+1)/2個乘法,效率很低 關鍵:採用遞迴式 Pn(x) = An*x^n + An-1*x^(n-1)
演算法設計與分析:第二章 遞迴 2.6基於遞迴的插入排序
/* 基於遞迴的插入排序: 將待插入的關鍵字插入到已經排好序的序列中 遞迴基:當陣列元素個數n=1時,只有一個元素,已經是排序的 遞迴步:如果前面k-1個元素已經排序,只要將第k個元素逐漸與 前面k-1個元素比較,把他插入到適當位置,即可完成k個元素的排序 遞迴的規律總
《演算法設計與分析》第十一週作業
《演算法設計與分析》第十一週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第十一週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
《演算法設計與分析》第十二週作業
《演算法設計與分析》第十二週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第十二週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
演算法設計與分析》第十週作業
《演算法設計與分析》第十週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第十週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
《演算法設計與分析》第九周作業
《演算法設計與分析》第九周作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第九周作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
《演算法設計與分析》第八週作業
《演算法設計與分析》第八週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第八週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
《演算法設計與分析》第七週作業
《演算法設計與分析》第七週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第七週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
演算法設計與分析》第六週作業
《演算法設計與分析》第六週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第六週作業 @[toc] 題目概要 思路 具體實現 心得 原始碼:
《演算法設計與分析》第五週作業
《演算法設計與分析》第五週作業 標籤(空格分隔): 課堂作業 文章目錄 《演算法設計與分析》第五週作業 @[toc] 前言 題目概要 思路 具體實現 心得 原始碼: