• <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_搜索

            導航

            <2010年10月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久天天躁狠狠躁夜夜2020一| 亚洲国产精品久久久久网站| 午夜精品久久久久久久无码| 无码人妻少妇久久中文字幕蜜桃 | 精品久久久久久久国产潘金莲| 思思久久99热免费精品6| 亚洲va中文字幕无码久久不卡 | 97精品伊人久久久大香线蕉| 久久亚洲AV无码精品色午夜| 91精品国产91热久久久久福利 | 欧美久久久久久精选9999| 久久久久女教师免费一区| 亚洲精品美女久久久久99| 日本高清无卡码一区二区久久| 久久青青草原精品影院| 国产精品99久久久久久www| 国产精品99久久免费观看| 久久久国产精华液| 亚洲女久久久噜噜噜熟女| 久久精品国产日本波多野结衣| 伊人色综合九久久天天蜜桃| 99精品国产99久久久久久97| 久久成人国产精品免费软件| 国产亚洲精午夜久久久久久| 人妻中文久久久久| 久久国内免费视频| 久久精品国产亚洲一区二区三区| 久久婷婷是五月综合色狠狠| 欧美日韩精品久久久久| 久久精品一区二区影院| 久久天天躁夜夜躁狠狠| 天天躁日日躁狠狠久久| 久久婷婷人人澡人人| 色综合久久久久综合体桃花网| 国产高潮久久免费观看| 性欧美丰满熟妇XXXX性久久久 | 奇米影视7777久久精品| 久久影院午夜理论片无码| 日本福利片国产午夜久久| 亚洲综合日韩久久成人AV| 日韩va亚洲va欧美va久久|