• <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 閱讀(272) 評論(0)  編輯 收藏 引用 所屬分類: B_搜索

            導航

            <2010年7月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲AV无码一区东京热久久| 久久久久九九精品影院| 久久AV高潮AV无码AV| 久久久无码精品亚洲日韩蜜臀浪潮| 久久人人爽人人爽人人片AV东京热| 亚洲精品乱码久久久久久中文字幕| 亚洲乱码精品久久久久..| 久久96国产精品久久久| 亚洲性久久久影院| 久久99毛片免费观看不卡| 久久久综合香蕉尹人综合网| 国产aⅴ激情无码久久| 国产成人久久777777| 亚洲中文精品久久久久久不卡 | 国产精品伦理久久久久久| 国产精品久久久久久久久久影院 | 青青草原综合久久大伊人精品| 久久亚洲天堂| 精品国产热久久久福利| 久久精品亚洲日本波多野结衣| 亚洲国产成人精品女人久久久 | 91亚洲国产成人久久精品网址| 思思久久好好热精品国产| 国产精品99久久精品爆乳| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久电影网一区| 99国产精品久久| 久久久久免费看成人影片| 久久久国产精华液| 久久成人小视频| 国产精品久久久久蜜芽| 亚洲国产视频久久| 亚洲人成无码www久久久| 四虎亚洲国产成人久久精品| 久久精品国产亚洲精品| 狠狠精品久久久无码中文字幕| 国产99久久久久久免费看| 日本精品久久久中文字幕| 亚洲精品高清国产一久久| 欧美综合天天夜夜久久| 成人国内精品久久久久影院VR|