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;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2012-07-23 17:21  AC_Von  阅读(247)  评论(0编辑  收藏  举报