• HDU 多校联合第一场


    1001

    开始没读懂题意,蛋疼的英语。。。

    题意是先给26个字母,第i位表示把第i个字母翻译成那个字母。然后再给一个串,前边某些是密文,后边某些是明文。让求的是如果后边的某些明文是前边那些密文翻译过来的一部分。那么把后边的明文补全使得串最短。

    中文都说的好纠结。。。出题报告说是eKMP,偶暴力蹭过去的。。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    #include <stack>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    
    const int eps = 1e-6;
    const int inf = ~0u>>2;;
    typedef long long LL;
    
    using namespace std;
    
    const int N = 100010;
    
    int pre[N];
    char tmp[30], ts[30];
    char ss[N];
    char T[N], P[N];
    
    /*void Next(char* p, int n) {
        int i, k = -1;
        pre[0] = -1;
        for(i = 1; i < n; ++i) {
            while(k > -1 && p[k+1] != p[i]) k = pre[k];
            if(p[k+1] == p[i])  ++k;
            k = pre[k];
        }
    }
    
    bool KMP(char* T, char* p) {
        int n = strlen(T), m = strlen(p);
        Next(p, m);
        int i, k;
        k = -1;
        for(i = 0; i < n; ++i) {
            while(k > -1 && p[k+1] != T[i]) k = pre[k];
            if(p[k+1] == T[i])  ++k;
            if(k == m - 1)  return true;
        }
        return false;
    }*/
    
    bool match(char* T, char* P) {
        int i = 0, j = 0;
        while(T[i] != '\0' && P[j] != '\0')
            if(T[i++] != P[j++])    return false;
        return true;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int t, n, l, i, j, m;
        char c;
        scanf("%d", &t);
        while(t--) {
            scanf("%s%s", tmp, ss);
            for(i = 0; i < 26; ++i) {
                c = tmp[i];
                ts[c-'a'] = i+'a';
            }
            n = strlen(ss);
            l = (n + 1)/2;
            CL(T, 0); CL(P, 0);
            for(i = 0; i < l; ++i) {
                T[i] = ts[ss[i]-'a'];
            }
            T[i] = '\0';
            for(i = l; i < n; ++i) {
                for(m = 0, j = i; j < n; ++j) {
                    P[m++] = ss[j];
                }
                P[m] = '\0';
                //puts(T);
                //puts(P);
                if(match(T, P))   break;
                T[i] = ts[ss[i]-'a']; T[i+1] = '\0';
            }
            for(j = 0; j < i; ++j)  printf("%c", ss[j]);
            for(j = 0; j < i; ++j)  printf("%c", ts[ss[j]-'a']);
            cout << endl;
        }
        return 0;
    }

    1002

    dp题,好蛋疼。

    f[i+1][j][0] = (f[i+1][j][0] + f[i][j][0] + f[i][j][1]*2) % MOD;
    f[i+1][j+1][0] = (f[i+1][j+1][0] + f[i][j][0] + f[i][j][1]) % MOD;
    
    f[i+1][j][1] = (f[i+1][j][1] + f[i][j][1]) % MOD;
    f[i+1][j+1][1] = (f[i+1][j+1][1] + f[i][j][1]*2 + f[i][j][0]*2) % MOD;
    f[i+1][j+2][1] = (f[i+1][j+2][1] + f[i][j][1] + f[i][j][0]) % MOD;

    1003

    题意:找离当前position最近的蛋糕,如果左右蛋糕距离一样,则选择到position这个点时的方向继续走。。。

    方法1 set:

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    #include <stack>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    
    const int eps = 1e-6;
    const int inf = ~0u>>2;
    typedef long long LL;
    
    using namespace std;
    
    const int N = 100010;
    set<int> st;
    int num[N];
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int t, n, k, cas = 0;
        int a, b, d;
        LL ans, p, np, l, r;
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &k);
            st.clear();
            st.insert(0);
            CL(num, 0);
            p = 0; ans = 0;
            while(k--) {
                scanf("%d", &a);
                if(a == 0) {
                    scanf("%d", &b);
                    num[b]++;
                    st.insert(b);
                } else {
                    if(num[p])  {num[p]--; continue;}
    
                    set<int>::iterator it1, it2;
                    it1 = it2 = st.find(p);
                    l = r = -1;
                    if(it1 != st.begin())   l = *--it1;
                    if(++it2 != st.end()) r = *it2;
                    //printf("%lld %lld\n", l, r);
                    if(l == -1 && r == -1)  {continue;}
                    if(l == -1) {
                        ans += r - p; d = 1;
                        np = r; num[r]--;
                    } else if(r == -1) {
                        ans += p - l; d = 0;
                        np = l; num[l]--;
                    } else {
                        if(r - p == p - l) {
                            ans += r - p;
                            if(d == 1)  {np = r; num[r]--;}
                            else    {np = l; num[l]--;}
                        } else if(r - p > p - l) {
                            ans += p - l;
                            np = l; d = 0; num[l]--;
                        } else {
                            ans += r - p;
                            np = r; d = 1; num[r]--;
                        }
                    }
                    st.erase(p);
                    p = np;
                }
            }
            printf("Case %d: ", ++cas);
            cout << ans << endl;
        }
        return 0;
    }

    方法2 线段树:

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    #include <stack>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    
    const int eps = 1e-6;
    const int inf = ~0u>>2;;
    typedef long long LL;
    
    using namespace std;
    
    const int N = 100020;
    
    struct node {
        int l, r;
        int col, Max, Min;
    } tree[N<<2];
    
    void creat(int t, int l, int r) {
        tree[t].l = l;
        tree[t].r = r;
        tree[t].col = 0;
        tree[t].Max = -inf;
        tree[t].Min = inf;
        if(l == r)  return ;
        int mid = MID(l, r);
        creat(L(t), l, mid);
        creat(R(t), mid + 1, r);
    }
    
    void updata(int t, int p, int val) {
        if(tree[t].l == tree[t].r) {
            tree[t].col += val;
            if(tree[t].col) {tree[t].Max = tree[t].Min = p;}
            else    {tree[t].Max = -inf; tree[t].Min = inf;}
            return ;
        }
        int mid = MID(tree[t].l, tree[t].r);
        if(p <= mid) updata(L(t), p, val);
        else    updata(R(t), p, val);
    
        tree[t].Max = max(tree[L(t)].Max, tree[R(t)].Max);
        tree[t].Min = min(tree[L(t)].Min, tree[R(t)].Min);
    }
    
    int get_max(int t, int l, int r) {
        if(tree[t].l >= l && tree[t].r <= r) {
            return tree[t].Max;
        }
        int mid = MID(tree[t].l, tree[t].r);
        if(l > mid) return get_max(R(t), l, r);
        else if(r <= mid)   return get_max(L(t), l, r);
        else {
            return max(get_max(L(t), l, mid), get_max(R(t), mid + 1, r));
        }
    }
    
    int get_min(int t, int l, int r) {
        if(tree[t].l >= l && tree[t].r <= r) {
            return tree[t].Min;
        }
        int mid = MID(tree[t].l, tree[t].r);
        if(l > mid) return get_min(R(t), l, r);
        else if(r <= mid)   return get_min(L(t), l, r);
        else {
            return min(get_min(L(t), l, mid), get_min(R(t), mid + 1, r));
        }
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int t, n, m, cas = 0;;
        int p, np, l, r, d, a, b;
        LL ans;
        scanf("%d", &t);
        while(t--) {
            scanf("%d%d", &n, &m);
            p = ans = 0; d = 1;
            creat(1, 0, n + 1);
    
            while(m--) {
                scanf("%d", &a);
                if(a == 0) {
                    scanf("%d", &b);
                    updata(1, b, 1);
                } else {
                    l = get_max(1, 0, p);
                    r = get_min(1, p, n);
    
                    //printf("%d %d\n", l, r);
                    if(l <= -inf && r >= inf)   continue;
    
                    else if(l <= -inf) {
                        ans += r - p; np = r; d = 1;
                    } else if(r >= inf) {
                        ans += p - l; np = l; d = 0;
                    } else {
                        if(r - p == p - l) {
                            ans += r - p;
                            if(d == 1)  np = r;
                            else    np = l;
                        } else if(r - p > p - l) {
                            ans += p - l;
                            d = 0; np = l;
                        } else {
                            ans += r - p;
                            d = 1; np = r;
                        }
                    }
                    updata(1, np, -1);
                    p = np;
                }
            }
            printf("Case %d: ", ++cas);
            cout << ans << endl;
        }
        return 0;
    }

    1009

    看着就像搜索。。。可以用优先队列。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   x < y ? x : y
    #define Max(x, y)   x < y ? y : x
    #define E(x)    (1 << (x))
    
    const int eps = 1e-6;
    const int inf = ~0u>>2;
    typedef long long LL;
    
    using namespace std;
    
    const int N = 5002;
    
    struct node {
        int x, y, d;
        node(int a = 0, int b = 0, int c = 0) : x(a), y(b), d(c) {}
        bool operator < (const node& tmp) const {
            return d > tmp.d;    //优先级要搞清楚
        }
    };
    
    struct pos {
        int x;
        int y;
        pos() {}
        pos(int a, int b) : x(a), y(b) {}
    } stk[510];
    
    
    
    int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    
    char mp[N][N];
    bool vis[N][N];
    int n,  m, cost, t;
    
    bool inmap(int x, int y) {
        if(x < 0 || x >= n || y < 0 || y >= m)    return false;
        return true;
    }
    
    int bfs(int x, int y) {
        CL(vis, 0);
        priority_queue<node> q;    //注意这个要放到函数里,不然会MLE
        q.push(node(x, y, 0));
        int i, j, nx, ny;
        node u;
        vis[x][y] = true;
        while(!q.empty()) {
            u = q.top();
            q.pop();
    
            for(i = 0; i < 4; ++i) {
                nx = u.x + dir[i][0];
                ny = u.y + dir[i][1];
    
                if(!inmap(nx, ny) || vis[nx][ny] || mp[nx][ny] == '#')   continue;
    
                vis[nx][ny] = true;
    
                if(mp[nx][ny] == 'C')   return u.d;
                if(mp[nx][ny] == 'P') {
                    for(j = 0; j < t; ++j) {
                        q.push(node(stk[j].x, stk[j].y, u.d));
                    }
                }
                else if(mp[nx][ny] == '*') {
                    q.push(node(nx, ny, u.d + cost));
                }
            }
        }
        return -1;
    }
    
    int main() {
        //freopen("data.in", "r", stdin);
    
        int i, j, x, y, ans;
        while(~scanf("%d%d%d", &n, &m, &cost)) {
            for(i = 0; i < n; ++i) {
                scanf("%s", mp[i]);
            }
            t = 0;
            for(i = 0; i < n; ++i) {
                for(j = 0; j < m; ++j) {
                    if(mp[i][j] == 'Y') {x = i, y = j;}
                    else if(mp[i][j] == 'P') {
                        stk[t++] = pos(i, j);
                    }
                }
            }
            ans = bfs(x, y);
            if(ans == -1)   puts("Damn teoy!");
            else    printf("%d\n", ans);
        }
        return 0;
    }

     

  • 相关阅读:
    UITableViewCell分隔线
    Swift:Debug和Release状态下错误输出
    开发中遇到的那些坑
    code sign error 1
    Xcode头文件加锁
    UIPageControl显示图片
    关于RTKLIB资料整理和学习
    I2C中24C02从地址设置
    从库函数操作RCC的流程来理解偏移变量
    对于STM32别名区的理解 (转载)
  • 原文地址:https://www.cnblogs.com/vongang/p/2605291.html
Copyright © 2020-2023  润新知