比赛链接: http://www.bnuoj.com/bnuoj/contest_show.php?cid=3907

 

A. Daka

简单题!时间处理! 

# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;

typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>

# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)

struct Time
{
    int t, y, m, d; 
    Time(){};
    Time(int aa, int bb, int cc, int dd) : t(aa), y(bb), m(cc), d(dd) {}; 
};

int One(Time a, Time b)
{
    if (a.y == b.y && a.m == b.m && a.d == b.d)
        return 1;
    return 0;
}

int cmp(const Time &a, const Time &b)
{
    if (a.y == b.y)
    {
        if (a.m == b.m)
        {
            if (a.d == b.d)
                return a.t < b.t;
            return a.d < b.d;
        }
        return a.m < b.m;
    }
    return a.y < b.y;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    
    int i, j, k, l, h, m, s, t, yy, mm, dd;
    int f1, f2, c1, c2, t1, t2;
    int l1 = 7 * 3600, r1 = 8 * 3600 + 30 * 60;
    int l2 = 16 * 3600, r2 = 21 * 3600 + 30 * 60;
    int half = 30 * 60;
    vector<Time> u;
    c1 = c2 = 0; //morning / half
    while (scanf ("%d %d %d %d %d %d", &h, &m, &s, &yy, &mm, &dd) != EOF)
    {
        t = h * 3600 + m * 60 + s;
        u.pb(Time(t, yy, mm, dd));
    }
    sort (all(u), cmp);
    for (i = 0; i < sz(u); i++)
    {
        j = i;
        while (j < sz(u) && One(u[i], u[j]))
            j++;
        f1 = f2 = 0;
        for (k = i; k < j; k++)
        {
            int t1 = u[k].t;
            if (t1 >= l1 && t1 <= r1) f1 = 1;
        }
        t1 = u[i].t, t2 = u[j - 1].t;
        if (min (t2, r2) - max (t1, l2) >= half)
            f2 = 1;
        c1 += f1, c2 += f2;
        i = j - 1;
    }
    printf ("%d %d\n", 10 - min (10, c1), 20 - min (20, c2));
    return 0;
}
View Code

 

B. A Problem about Tree

 蛮好的题!倍增法求lca

如果lca(x, y) != y, 答案就是y的父节点!

否则通过从x 节点2分查找深度为dep[y] + 1的节点就是答案!

# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;

typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>

# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)

# define N 10005
# define M 20005

const int POW = 18;
int father[N];
int p[N][20], dep[N];
int num, head[N];

struct edge
{
    int u, v, next;
}e[M];

void addedge(int u, int v)
{
    e[num].u = u;
    e[num].v = v;
    e[num].next = head[u];
    head[u] = num++;
}

void dfs(int u, int fa)
{
    int i, v;
    father[u] = fa;
    dep[u] = dep[fa] + 1;
    p[u][0] = fa;
    for (i = 1; i < POW; i++)
        p[u][i] = p[p[u][i - 1]][i - 1];
    for (i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if (v == fa) continue;
        dfs(v, u);
    }
}

int lca(int a, int b)
{
    int i, d;
    if (dep[a] > dep[b]) swap(a, b);
    if (dep[a] < dep[b])   //调整深度
    {
        d = dep[b] - dep[a];
        for (i = 0; i < POW; i++)
            if (d & (1 << i))
                b = p[b][i];
    }
    if (a != b)
    {
        for (i = POW - 1; i >= 0; i--)
            if (p[a][i] != p[b][i])
                a = p[a][i], b = p[b][i];
        a = p[a][0], b = p[b][0];
    }
    return a;
}

void init()
{
    num = 0;
    mem (head, -1);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int T, i, j, n, m, u, v, x, y, d;
    scanf ("%d", &T);
    while (T--)
    {
        init();
        scanf ("%d %d", &n, &m);
        for (i = 1; i < n; i++)
        {
            scanf ("%d %d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
        dfs(1, 0);
        for (i = 1; i <= m; i++)
        {
            scanf ("%d %d", &x, &y);
            if (lca(x, y) != y)
                printf ("%d\n", father[y]);
            else
            {
                if (father[x] == y)
                    printf ("%d\n", x);
                else    //2分查找
                {
                    d = dep[x] - dep[y] - 1;
                    for (j = 0; j < POW; j++)
                        if (d & (1 << j))
                            x = p[x][j];
                    printf ("%d\n", x);
                }
            }
        }
    }
    return 0;
}
View Code

 

C.Word Ladder

枚举每一个字符串的每一位, 分别替换成其他25个字母! 替换完后的字符串如果存在就构建一条边!

构完图后跑一遍最短路就可以了! 

# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;

typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>

# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)

# define N 6005

map<string, int> Hash;
char s[N]; 
VI edge[N];
int dis[N], vis[N], n;

int spfa(int s, int t)
{
    int i, u, v;
    queue<int> q;
    for (i = 1; i <= n; i++)
        dis[i] = INF;
    dis[s] = 0, vis[s] = 1;
    q.push(s);
    while (!q.empty())
    {
        u = q.front();
        q.pop();
        for (i = 0; i <sz(edge[u]); i++)
        {
            v = edge[u][i];
            if (dis[u] + 1 < dis[v])
            {
                dis[v] = dis[u] + 1;
                if (!vis[v])
                {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
        vis[u] = 0;
    }
    return dis[t];
}

int main()
{
  //  freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    
    int i, j, k, u, v;
    vector<string> S;
    n = 0;
    while (scanf ("%s", s) != EOF)
    {
        if (!Hash[s]) Hash[s] = ++n;
        S.pb(s);
    }
    for (i = 0; i < sz(S); i++)
    {
//        cout << s << Hash[s] << endl;
        string s = S[i];
        for (j = 0; j < sz(s); j++)
            for (k = 0; k < 26; k++)
                if (s[j] - 'a' != k)
                {
                    string ts = s; 
                    ts = ts.replace(j, 1, 1, 'a' + k);
                    if (Hash[ts])
                    {
                        u = Hash[S[i]], v = Hash[ts];
                        if (u != v)
//                        printf ("%d -> %d\n", u, v);
                        edge[u].pb(v);
                    }
                }
    }
    int ans = spfa(1, 2);
    if (ans == INF)
        printf ("-1\n");
    else
        printf ("%d\n", ans + 1);
    return 0;
}
View Code

 

D.//O(n^3)DP + floyd 待补

 

E.//不会 

 

F.//找规律+矩阵,待补

 

G.//据说是费用流,待补

 

H.Selecting World Finals Teams on Mars I

简单题, DFS! 每个节点保存最大和次大,从叶子往上更新即可!

# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;

typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>

# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)

# define N 20005
# define M 30005

char s[N][105];
int w[N];
int fir[N], sec[N];
int num, head[N]; 
int Hash[N];

struct edge
{
    int u, v, next;
}e[M];

void addedge(int u, int v)
{
    e[num].u = u;
    e[num].v = v;
    e[num].next = head[u];
    head[u] = num++;
}

int dfs(int u, int fa)
{
    int i, v;
    if (w[u]) fir[u] = w[u];
    for (i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if (v == fa) continue;
        dfs(v, u);
        if (fir[v] > fir[u])
        {
            sec[u] = fir[u];
            fir[u] = fir[v];
            if (sec[v] > sec[u])
                sec[u] = sec[v];
        }
        else if (fir[v] > sec[u])
                sec[u] = fir[v];
    }
}

void init()
{
    num = 0;
    mem (head, -1);
}

int cmp(int a, int b)
{
    return w[a] > w[b];
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    int i, n, m, u, v;
    VI ans;
    while (scanf ("%d %d", &n, &m) != EOF)
    {
        init();
        clr (ans);
        mem (w, 0);
        mem (fir, 0);
        mem (sec, 0);
        mem (Hash, 0);
        for (i = 1; i < n + m; i++)
        {
            scanf ("%d %d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
        for (i = n + 1; i <= n + m; i++)
            scanf ("%s %d", s[i], &w[i]);
        dfs(1, 0);
//        printf ("*******************\n");
//        for (i = 1; i <= n + m; i++)
//            printf ("%d : %d %d\n", i, fir[i], sec[i]);
//        printf ("*******************\n");
        for (i = head[1]; i != -1; i = e[i].next)
        {
            v = e[i].v;
            if (fir[v] != 0) Hash[fir[v]] = 1;
            if (sec[v] != 0) Hash[sec[v]] = 1;
//            printf ("%d : %d %d\n", v, fir[v], sec[v]);
        }
        for (i = n + 1; i <= n + m; i++)
            if (Hash[w[i]])
                ans.pb(i);
        sort (all(ans), cmp);
        for (i = 0; i < sz(ans); i++)
            printf ("%s\n", s[ans[i]]);
    }
    return 0;
}
View Code

 

I.//不会

 

J.Selecting World Finals Teams on Mars II

蛮好的题, 线段树! 按3个键值分别从小到大排序, 每次找小于第2个键值中第3个键值最小的值,如果最小值小于这个3元组的第3个键值, 则这个3元组不计数!

否则Count++,  输出Count即可!

# include<map>
# include<set>
# include<list>
# include<cmath>
# include<queue>
# include<stack>
# include<vector>
# include<string>
# include<cstdio>
# include<cstring>
# include<iostream>
# include<algorithm>
# include<functional>
using namespace std;

typedef pair<int,int> PII;
# define INF 1<<30
# define LL long long
# define MOD 1000000007
# define VI vector<int>
# define VLL vector<LL>
# define VPII vector<PII>
# define VS vector<string>
# define PII pair<int,int>

# define F first
# define S second
# define mp make_pair
# define pb push_back
# define lb lower_bound
# define up upper_bound
# define lowbit(x)(x&-x)
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
# define clr(x) (x).clear()
# define sz(x) ((int)(x).size())
# define all(x) (x).begin(),(x).end()
# define mem(x,y) memset(x,y,sizeof(x))
# define rep(i,a,b) for(i=(a);i<=(b);i++))
# define forall(it,c) for(typeof((c).begin())it=(c).begin();it!=(c).end();it++)

# define N 100005
# define M 105

int Min[M << 2];

struct node
{
    int a, b, c;
}e[N];


void PushUp(int rt)
{
    Min[rt] = min (Min[rt << 1], Min[rt << 1 | 1]);
}

void Update(int pos, int x, int l, int r, int rt)
{
    int m;
    if (l == r)
    {
        Min[rt] = min (Min[rt], x);
        return;
    }
    m = (l + r) >> 1;
    if (pos <= m) Update(pos, x, lson);
    else Update(pos, x, rson);
    PushUp(rt);
}

int Query(int L, int R, int l, int r, int rt)
{
    int ans = INF, m;
    if (L <= l && R >= r)
        return Min[rt];
    m = (l + r) >> 1;
    if (L <= m) ans = min (ans, Query(L, R, lson));
    if (R > m) ans = min (ans, Query(L, R, rson));
    return ans;
}

int cmp(const node &a, const node &b)
{
    if (a.a == b.a)
    {
        if (a.b == b.b)
            return a.c < b.c;
        return a.b < b.b;
    }
    return a.a < b.a;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

    int i, j, k, n, ans;
    while (scanf ("%d", &n) != EOF)
    {
        ans = n;
        fill(Min, Min + 400, INF);
        for (i = 1; i <= n; i++)
            scanf ("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
        sort (e + 1, e + n + 1, cmp);
        for (i = 1; i <= n; i++)
        {
            j = i;
            while (j <= n && e[j].a == e[i].a)
                j++;
            for (k = i; k < j; k++)
            {
                if (e[k].b == 1) continue;
                if (Query(1, e[k].b - 1, 1, 100, 1) < e[k].c)
                    ans--;
            }
            for (k = i; k < j; k++)
                Update(e[k].b, e[k].c, 1, 100, 1);
            i = j - 1;
        }
        printf ("%d\n", ans);
    }
    return 0;
}
View Code