Codeforces Round #173 (Div. 2)

http://codeforces.com/contest/282

A:水,找到中间的算符,处理就行。

B:

话说比赛的时候竟然没有想法,无语了。给出n对数,ai,bi ;    ai + bi = 1000 ,求满足sa表示美对数取a的和与sb每对数取b的和之间的差值的绝对值小于等于500。对于每一对数要么取a,要么取b. 取A同A表示取b用G表示,输出最后的结果如果不存在输出-1

我们只要 贪心的选择,如果选A满足就给sa,如果选b满足就给sb,这样走下来就行。

View Code
By E_star, contest: Codeforces Round #173 (Div. 2), problem: (B) Painting Eggs, Accepted, #
 //#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#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))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);
#define inf 0x7f7f7f7f

#define M 107
#define N 1000007
using namespace std;

int a[N],b[N],ans[N];

int Abs(int x)
{
    if (x >= 0) return x;
    else return (-x);
}
int main()
{
    int n;
    int i,j;
    while (~scanf("%d",&n))
    {
        for (i = 0; i < n; ++i)
        {
            scanf("%d%d",&a[i],&b[i]);
        }
        int sa = 0;
        int sb = 0;
        for (i = 0; i < n; ++i)
        {
//            printf("%d %d\n",sa + a[i] - sb,sa - (sb + b[i]));
            if (Abs(sa + a[i] - sb) <= 500)
            {
                sa += a[i];
                ans[i] = 0;
            }
            else if (Abs(sa - (sb + b[i])) <= 500)
            {
                sb += b[i];
                ans[i] = 1;
            }
            else
            {
                break;
            }
        }
        if (i < n)
        {
            printf("-1\n");
        }
        else
        {
            for (i = 0; i < n; ++i)
            {
                if (ans[i] == 0) printf("A");
                else printf("G");
            }
            printf("\n");
        }
    }
    return 0;
}

 

C:

       xor   or

1 1   0     1

0 1   1     1

1 0   1     1

0 0   0     0

观察可知, 1 1 组和会减少一个1, 1 0 或 01 组和会增加一个1.我们只需要判断1的个数即可,只要a1 > b1 我们就可以通过 11来减少1 达到b状态,  a1 == b1 肯定就想相等了(1与0的个数两个状态时相等的) a1 < b1 我们就可以通过01来增加1达到b状态了。(我们需要注意的是,a1 > b1时,注意b1是否为0 ,因为a1不会变为0个1的状态,同理a1 < b1一样注意0的状态)

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#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))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);
#define inf 0x7f7f7f7f

#define M 107
#define N 1000007
using namespace std;

char a[N];
char b[N];

int main()
{
    int i,j;
    int a1,a0,b1,b0;
    a1 = a0 = b1 = b0 = 0;
    scanf("%s%s",a,b);
    int La = strlen(a);
    int Lb = strlen(b);
    if (La != Lb)
    {
        printf("NO\n");
    }
    else
    {
        for (i = 0; i < La; ++i)
        {
            if (a[i] == '0') a0++;
            else a1++;

            if (b[i] == '0') b0++;
            else b1++;
        }
        if (a1 == b1) printf("YES\n");
        else if (a1 > b1)
        {
            if (b1 == 0) printf("NO\n");
            else printf("YES\n");
        }
        else if (a1 < b1)
        {
            if (a1 == 0) printf("NO\n");
            else printf("YES\n");
        }
    }
    return 0;
}

 

D:

当n  == 1时 是巴什博奕

当n == 2时是 威佐夫博奕

当n == 3时是尼姆博弈(这里需要证明一下,对于3堆,同时取每一堆相同的个数,不会影响)

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#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))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 150
#define N 4100007
using namespace std;

int a[4];


int solve(int a,int b)
{
    if (a > b) swap(a,b);
    int k = b - a;
    int ak = k*(1 + sqrt(5))/2;
    if (ak == a) return 0;
    else return 1;
}
int main()
{
    int n,i;
    while (~scanf("%d",&n))
    {
        int flag = 0;
        for (i = 0; i < n; ++i) scanf("%d",&a[i]);

        if (n == 1) flag = a[0];
        else if (n == 2) flag = solve(a[0],a[1]);
        else flag = a[0]^a[1]^a[2];
        if (flag != 0) printf("BitLGM\n");
        else printf("BitAryo\n");
    }

    return 0;
}

 

E:

给出n个数求前P个一会的结果与后q个抑或的结果之间抑或的最大结果。

思路:Trie树 + 贪心

首先我们将所前i个数抑或的结果(二进制)存放到Trie树种,然后枚举后缀,在Trie树上贪心的选择与之抑或最大的值。这里最关键的是题目要求不能存在前缀与后缀相交,但是我们贪心的选择前缀时,确实没有排除相交的可能,但是我们想一想的话,如果存在相交,他们两个在疑惑不久取消了吗,之间相当于没有相交。经典的题目...

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll __int64
#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))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);


#define M 150
#define N 4100007
using namespace std;

struct node
{
    node *next[2];
    ll flag;
}*head;

node H[N];
int h;
int n;
int bit[44];
ll a[100007];

node *newnode()
{
    node *p = &H[h++];
    p->next[0] = NULL;
    p->next[1] = NULL;
    p->flag = 0;
    return p;
}
void insert(ll no)
{
    int i;
    CL(bit,0);
    for (i = 0; i <= 40; ++i)
    {
        bit[i] = (1&(no>>i));
    }
    node *p = head;
    for (i = 40; i >= 0; --i)
    {
        if (p->next[bit[i]] == NULL)
        {
            p->next[bit[i]] = newnode();
        }
        p = p->next[bit[i]];
    }
    p->flag = no;
}
ll query(ll no)
{
    int i;
    CL(bit,0);
    for (i = 0; i <= 40; ++i)
    {
       bit[i] = (1&(no>>i));
    }
    node *p = head;
    for (i = 40; i >= 0; --i)
    {
        if (p->next[bit[i]^1]) p = p->next[bit[i]^1];
        else p = p->next[bit[i]];
    }
    return (no^p->flag);
}
int main()
{
    int i;
    scanf("%d",&n);
    h = 0;
    head = newnode();
    ll sum = 0;
    ll ans = 0;
    for (i = 0; i < n; ++i)
    {
        scanf("%I64d",&a[i]);
        sum ^= a[i];
        insert(sum);
        ans = max(sum,ans);
    }
    sum = 0;
    for (i = n - 1; i >= 0; --i)
    {
        sum ^= a[i];
        ans = max(ans,query(sum));
    }
    printf("%I64d\n",ans);
    return 0;
}

 

 

 

posted @ 2013-03-22 18:00  E_star  阅读(282)  评论(0编辑  收藏  举报