Wenbin 的个人资料Wenbin Dai's Space照片日志列表 工具 帮助

日志


6月27日

SRM286 - InfiniteSoup

http://www.topcoder.com/stat?c=problem_statement&pm=6017&rd=8083

一道很好的题目,有几个tricky的地方需要注意:

1)对于[0,k][0,k]内的任一点(x,y),该ray等同于(0,0)到(x%r,y%c)的ray。如果用brute-force枚举,即便用了KMP也会超时。

2)对于水平和竖直方向的ray,不要hard-code加到要考虑的list里面(考虑grid为{"a"}这样的情况),还是用gcd来判断。

3)用KMP而不是brute-force做string-match。

 

int gcd(int a, int b) {
    while (b != 0) {
        a %= b;
        a ^= b ^= a ^= b;
    }
    return a;
}

vector<vector<int> > suffixes;

vector<int> BuildSuffix(string pattern) {
    int lp = pattern.length();
    vector<int> pi(lp, -1);
    int k = -1;
    FOR(q,1,lp-1) {
        while (k >= 0 && pattern[k + 1] != pattern[q]) k = pi[k];
        if (pattern[k + 1] == pattern[q]) ++k;
        pi[q] = k;
    }
    return pi;
}

bool StringMatchKMP(string text, string pattern, vector<int> suffix) {
    int lt = text.length(), lp = pattern.length();
    int k = -1;
    REP(i,lt) {
        while (k >= 0 && pattern[k + 1] != text[i]) k = suffix[k];
        if (pattern[k + 1] == text[i]) ++k;
        if (k == lp - 1) return true;
    }
    return false;
}

int cnt[40][40];

class InfiniteSoup {
public:
    vector <int> countRays(vector <string> g, vector <string> words, int k) {
        int r = g.size(), c = g[0].length();

        suffixes.clear();
        REP(i,words.size()) suffixes.push_back(BuildSuffix(words[i]));

        memset(cnt, 0, sizeof(cnt));
        FOR(i,0,k) {
            FOR(j,0,k) {
                if (gcd(i, j) == 1) ++cnt[i % r][j % c];
            }
        }

        vector <int> res(words.size(), 0);

        REP(i,r) {
            REP(j,c) {
                if (cnt[i][j] > 0) {
                    string str = "";
                    int tr = 0, tc = 0;
                    do {
                        str += g[tr][tc];
                        tr = (tr + i) % r, tc = (tc + j) % c;
                    } while (tr || tc);

                    string t = str;
                    REP(k,50) t += str[k % str.length()];

                    REP(k,words.size()) {
                        if (StringMatchKMP(t, words[k], suffixes[k])) res[k] += cnt[i][j];
                    }
                }
            }
        }

        return res;
    }
};

评论

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。

若要添加评论,请使用您的 Windows Live ID 登录(如果您使用过 Hotmail、Messenger 或 Xbox LIVE,您就拥有 Windows Live ID)。登录


还没有 Windows Live ID 吗?请注册

引用通告

此日志的引用通告 URL 是:
http://daiwb.spaces.live.com/blog/cns!B66E17478A932BF6!901.trak
引用此项的网络日志