Codeforces Round #294 (Div. 2) ABCDE

A - A and B and Chess

#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

char str[100][100];
int w[200];

int main ()
{
    memset (w, 0, sizeof(w));
    w['R'] = w['r'] = 5;
    w['Q'] = w['q'] = 9;
    w['N'] = w['n'] = 3;
    w['P'] = w['p'] = 1;
    w['B'] = w['b'] = 3;
    while (~scanf("%s", str[0]))
    {
        for (int i = 1; i < 8; ++i)
        {
            scanf("%s", str[i]);
        }
        int a = 0;
        int b = 0;
        for (int i = 0; i < 8; ++i)
        {
            for (int j = 0; j < 8; ++j)
            {
                if (str[i][j] >= 'A' && str[i][j] <= 'Z')
                {
                    a += w[str[i][j]];
                }
                else if (str[i][j] >= 'a' && str[i][j] <= 'z')
                {
                    b += w[str[i][j]];
                }
            }
        }
        if (a > b)
        {
            printf("White\n");
        }
        else if (a < b)
        {
            printf("Black\n");
        }
        else
        {
            printf("Draw\n");
        }
    }
    return 0;
}

B - A and B and Compilation Errors 分别输入n ,n-1, n-2个数,问少掉的两个数是什么。暴力for过去找就行了

#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
#define asd puts("sdasdasdasdasd");
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 200050;

int a[N], c[N];

int main()
{
    int n;
    scanf("%d", &n);
    int i;
    for( i = 1; i <= n; i++ )
        scanf("%d", &a[i]);
    sort( a+1, a+1+n );
    for( i = 1; i < n; i++ )
        scanf("%d", &c[i]);
    sort( c+1, c+n );
    int z, x;
    for( i = 1; i < n; i++ )
    {
        if( a[i] != c[i] )
        {
            z = a[i];
            break;
        }
    }
    if( i == n )
        z = a[i];
    for( i = 1; i < n-1; i ++ )
    {
        scanf("%d", &a[i]);
    }
    sort( a+1, a+n-1 );
    for( i = 1; i < n-1; i++ )
    {
        if( a[i] != c[i] )
        {
            x = c[i];
            break;
        }
    }
    if( i == n-1 )
        x = c[i];
    printf("%d\n%d\n", z, x);
    return 0;
}

C - A and B and Team Training 贪心,暴力大水题

#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int n, m;

int main ()
{
    while (~scanf("%d%d", &n, &m))
    {
        int ans = 0;
        while (n + m >= 3)
        {
            if (n > m && n >= 2 && m >= 1)
            {
                n -= 2;
                --m;
                ++ans;
            }
            else if (n <= m && m >= 2 && n >= 1)
            {
                m -= 2;
                --n;
                ++ans;
            }
            if (n <= 0 || m <= 0)
            {
                break;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
D - A and B and Interesting Substrings  给出A对26个字符的好感,给出一个字符串,问这个字符串中有多少个子串满足:子串去掉第一个后最后一个字符之后剩下的字符的好感度和为0,。记录前缀和,边记边算即可


#include <map>
#include <set>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int w[30];
char str[200100];
map <LL, LL> use[30];

int main ()
{
    while (~scanf("%d", &w[0]))
    {
        for (int i = 0; i < 30; ++i)
        {
            use[i].clear();
        }
        for (int i = 1; i <= 26; ++i)
        {
            scanf("%d", &w[i]);
        }
        scanf("%s", str);
        LL sum = 0;
        int len = strlen (str);
        LL ans = 0;
        for (int i = 0; i < len; ++i)
        {
            int pos = str[i] - 'a';
            if (use[pos][sum] != 0)
            {
                ans += use[pos][sum];
            }
            sum += w[pos];
            ++use[pos][sum];
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

E - A and B and Lecture Rooms :给出一棵树,问其中两个节点走到同一个节点的步数相同,这样的节点有多少个。

dfs预处理出每个节点的深度,然后求出a, b两个点的中间那个点(a,b到该点最近且步数相同),求出该点子树的大小即可。注意处理细节

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

const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

const int N = 101010;
int num[N];
int head[N];
int tot;
int deep[N];
int p[N][30];

struct node
{
    int to;
    int next;
}edge[N << 1];

void addedge (int from, int to)
{
    edge[tot].to = to;
    edge[tot].next = head[from];
    head[from] = tot++;
}

void dfs (int u, int fa)
{
    for (int i = head[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].to;
        if (v == fa)
        {
            continue;
        }
        deep[v] = deep[u] + 1;
        p[v][0] = u;
        dfs (v, u);
    }
}

int lca (int a, int b)
{
    if (deep[a] < deep[b])
    {
        swap (a, b);
    }
    int d = deep[a] - deep[b];
    for (int i = 0; i < 30; ++i)
    {
        if (d & (1 << i))
        {
            a = p[a][i];    
        }
    }
    if (a == b)
    {
        return a;
    }
    for (int i = 29; i >= 0; --i)
    {
        if (p[a][i] != p[b][i])
        {
            a = p[a][i];
            b = p[b][i];
        }
    }
    return p[a][0];
}

int dfs2 (int u, int fa)
{
    num[u] = 1;
    for (int i = head[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].to;
        if (v == fa)
        {
            continue;
        }
        num[u] += dfs2 (v, u);
    }
    return num[u];
}

int main ()
{
    int n;
    while (~scanf("%d", &n))
    {
        int u, v;
        memset (head, -1, sizeof(head));
        tot = 0;
        for (int i = 0; i < n - 1; ++i)
        {
            scanf("%d%d", &u, &v);
            addedge (u, v);
            addedge (v, u);
        }
        dfs(1, -1);
        memset (num, 0, sizeof(num));
        deep[1] = 0;
        dfs2 (1, -1);
        for (int j = 1; j < 30; ++j)
        {
            for (int i = 1; i <= n; ++i)
            {
                p[i][j] = p[p[i][j - 1]][j - 1];
            }
        }
        int m;
        scanf("%d", &m);
        while (m--)
        {
            scanf("%d%d", &u, &v);
            if (u == v)
            {
                printf("%d\n", n);
                continue;
            }
            int LCA = lca (u, v);
            int d1 = deep[u] - deep[LCA];
            int d2 = deep[v] - deep[LCA];
            if (d1 != d2)
            {
                if (abs(d1 - d2) & 1)
                {
                    printf("0\n");
                }
                else
                {
                    if (deep[u] < deep[v])
                    {
                        swap (u, v);
                    }
                    int dist = (d1 + d2) / 2;
                    int uu = u;
                    for (int k = 0; k < 30; ++k)
                    {
                        if (dist & (1 << k))
                        {
                            uu = p[uu][k];
                        }
                    }
                    --dist;
                    int vv = u;
                    for (int k = 0; k < 30; ++k)
                    {
                        if (dist & (1 << k))
                        {
                            vv = p[vv][k];
                        }
                    }
                    printf("%d\n", num[uu] - num[vv]);
                }
            }
            else
            {
                    int uu = u;
                    int dist = d1 - 1;
                    for (int k = 0; k < 30; ++k)
                    {
                        if (dist & (1 << k))
                        {
                            uu = p[uu][k];
                        }
                    }
                    int vv = v;
                    for (int k = 0; k < 30; ++k)
                    {
                        if (dist & (1 << k))
                        {
                            vv = p[vv][k];
                        }
                    }
                    printf("%d\n", n - num[vv] - num[uu]);
            }
        }
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值