• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            A Za, A Za, Fighting...

            堅信:勤能補拙

            PKU 3373 Changing Digits

            問題:
            http://acm.pku.edu.cn/JudgeOnline/problem?id=3373

            參考:
            http://blog.csdn.net/logic_nut/archive/2009/10/29/4740951.aspx
            http://iaml.is-programmer.com/posts/8249.html (這個應該是SYSU的哈哈,里面有西西里)

            思路:
            這個題是真不會做,即使是看別人代碼都看了快兩天,艾...

            首先要解決的問題是如何求大數的模(這里大數用字符串表示)?
            我們知道對于取模運算有: (a+b)%k = ((a%k)+(b%k))%k
                                                 (ab)%k = ((a%k)(b%k))%k
            對于0-9的每個數,可以將其在個、十、百、千...位時模k的結果保存到一張表中: mod_arr
            這樣,修改這個大數的任何一位而模k的新結果可以在O(1)時間內取得 
             1 char num[MAX_LEN];
             2 int hash[MAX_MOD];
             3 int mod_arr[MAX_LEN][10];
             4 int k, len, tmp[MAX_LEN], tmp2[MAX_LEN], start_mod;
             5 int head, tail;
             6 struct EACH {
             7     int digits[MAX_LEN];
             8     int remainder;
             9     int index;
            10 } queue[MAX_MOD];
            11 
            12 void
            13 init()
            14 {
            15     int i, j;
            16     len = strlen(num);
            17     for(j=0; j<10; j++)
            18         mod_arr[0][j] = j%k;
            19     for(i=1; i<len; i++)
            20         for(j=0; j<10; j++)
            21             mod_arr[i][j] = (mod_arr[i-1][j]*10)%k;
            22     start_mod = 0;
            23     for(i=0; i<len; i++) {
            24         tmp[i] = tmp2[i] = num[len-i-1]-'0';
            25         start_mod += (mod_arr[i][num[len-i-1]-'0']);
            26     }
            27     start_mod %= k;
            28     head = -1;
            29     tail = 0;
            30     memset(hash, 0sizeof(hash));
            31     memset(queue, 0sizeof(queue));
            32 }

            第一篇參考鏈接里是用DFS來做的,可惜我對于其中用于記憶化搜索的remember數組始終不理解,結果TLE
            更加容易理解的方案是BFS,每次擴展改變一位數字
            使用BFS的問題是如何判重?參考第二篇文章(繁瑣的C++語法,沒認真看呵呵),使用余數判重,其實還不是太理解

            代碼:
             1 void
             2 bfs()
             3 {
             4     int i, j, t, cur_rem, cur_index;
             5     queue[tail].remainder = start_mod;
             6     memcpy(queue[tail].digits, tmp, sizeof(int)*len);
             7     queue[tail].index = len-1;
             8     hash[start_mod] = 1;
             9     while(head < tail) {
            10         ++head;
            11         cur_rem = queue[head].remainder;
            12         cur_index = queue[head].index;
            13         memcpy(tmp, queue[head].digits, sizeof(int)*len);
            14         if(cur_rem == 0) {
            15             for(i=len-1; i>=0; i--)
            16                 printf("%d", tmp[i]);
            17             printf("\n");
            18             return;
            19         }
            20         /* changing digits: from least (smaller than itself) */
            21         for(i=cur_index; i>=0; i--) {
            22             for(j=0; j<tmp2[i]; j++) {
            23                 if(i==len-1 && j==0)
            24                     continue;
            25                 t = cur_rem + mod_arr[i][j] - mod_arr[i][tmp2[i]] + k; /* O(1) to find the new remainder */
            26                 t = t % k;
            27                 tmp[i] = j;
            28                 if(!hash[t]) {
            29                     ++tail;
            30                     queue[tail].remainder = t;
            31                     queue[tail].index = i-1;
            32                     memcpy(queue[tail].digits, tmp, sizeof(int)*len);
            33                     hash[t] = 1;
            34                 }
            35             }
            36             tmp[i] = tmp2[i];
            37         }
            38         /* changing digits: to max (greater than itself) */
            39         for(i=0; i<=cur_index; i++) {
            40             for(j=tmp2[i]+1; j<10; j++) {
            41                 t = cur_rem + mod_arr[i][j] - mod_arr[i][tmp2[i]] + k;
            42                 t = t % k;
            43                 tmp[i] = j;
            44                 if(!hash[t]) {
            45                     ++tail;
            46                     queue[tail].remainder = t;
            47                     queue[tail].index = i-1;
            48                     memcpy(queue[tail].digits, tmp, sizeof(int)*len);
            49                     hash[t] = 1;
            50                 }
            51                 tmp[i] = tmp2[i];
            52             }
            53         }
            54     }
            55 }

            posted on 2010-08-02 12:46 simplyzhao 閱讀(275) 評論(0)  編輯 收藏 引用 所屬分類: B_搜索

            導航

            <2011年10月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久天天躁狠狠躁夜夜不卡 | 精品精品国产自在久久高清| 国产69精品久久久久9999APGF| 伊人久久大香线蕉av不卡| 久久er99热精品一区二区| 免费国产99久久久香蕉| 中文精品99久久国产| 国产成人久久AV免费| 亚洲国产小视频精品久久久三级| 久久免费的精品国产V∧| 人妻中文久久久久| 国产69精品久久久久777| 热久久最新网站获取| 国产成人精品免费久久久久| 亚洲人成网站999久久久综合 | 亚洲AV日韩精品久久久久久久| 久久99国产亚洲高清观看首页| 国产精品99久久久久久宅男小说| 国产精品久久久久久福利漫画| 久久中文字幕人妻熟av女| 国产亚洲精久久久久久无码AV| 色婷婷久久综合中文久久蜜桃av| 久久影视国产亚洲| 久久精品?ⅴ无码中文字幕| 91精品国产综合久久久久久| 亚洲国产精品成人久久| 久久午夜无码鲁丝片秋霞| 久久综合九色欧美综合狠狠| 日本精品久久久久中文字幕8| 久久精品国产精品亚洲毛片| 久久精品国产日本波多野结衣 | 国产AⅤ精品一区二区三区久久| 奇米影视7777久久精品| 亚洲欧美伊人久久综合一区二区 | 欧美熟妇另类久久久久久不卡| 亚洲国产一成久久精品国产成人综合 | 国产精品一区二区久久国产| 亚洲精品午夜国产VA久久成人| 欧美成人免费观看久久| 亚洲精品99久久久久中文字幕| 久久毛片一区二区|