Codeforces Round #228 (Div. 2) 题解

A.Fox and Number Game

题意:有一列数a(100),可以进行多次操作,每次选出数组中的两个数xi>xj,然后xi = xi – xj,问这n个数的和最小是多少

思路:数组中的数最后都会变成这n个数的gcd,所以求出数组的gcd,然后乘以数组个数就是最后的答案

代码:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    scanf("%d", &n);
    int ans;
    scanf("%d", &ans);
    for(int i = 2; i <= n; i++) {
        int x;
        scanf("%d", &x);
        ans = __gcd(ans, x);
    }
    printf("%d\n",ans * n);
    return 0;
}
View Code

B. Fox and Cross

    题意:给一张只含有’.’,’#’,的地图,问这种地图中的#号是不是由

     .#.

            ###

            .#.

这样的十字构成的

    思路:遇到的每一个十字都填上,贪心的填,最后检查一下是否还有#号

    代码:

#include <bits/stdc++.h>
using namespace std;

char mp[105][105];

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cin>>mp[i][j];
        }
    }
    for(int i = 2; i < n; i++) {
        for(int j = 2; j < n; j++) {
            if(mp[i][j] == '#' &&
               mp[i - 1][j] == '#' &&
               mp[i + 1][j] == '#' &&
               mp[i][j - 1] == '#' &&
               mp[i][j + 1] == '#') {
                mp[i][j] = '.';
                mp[i + 1][j] = '.';
                mp[i - 1][j] = '.';
                mp[i][j + 1] = '.';
                mp[i][j - 1] = '.';
           }
        }
    }
    bool ok = true;
    for(int i = 1; i <= n && ok; i++) {
        for(int j = 1; j <= n && ok; j++) {
            if(mp[i][j] == '#') ok = false;
        }
    }
    if(ok) puts("YES");
    else puts("NO");
    return 0;
}
View Code

C. Fox and Box Accumulation

    题意:有n个箱子,每个箱子有一个ai,表示这个箱子上面最多还能放几个箱子,问这n个箱子最少放城几堆

    思路:二分最后放成几堆,对于mid堆,先把最大的mid的放上去,然后每次维护这一堆还能放几个

    代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 107;
int n;
int a[maxn], c[maxn];

bool cmp(int x, int y)
{
    return x > y;
}
bool check(int x)
{
    for(int i = 1; i <= x; i++) c[i] = a[i];
    int j = 1;
    for(int i = x + 1; i <= n; i++) {
        bool ok = true;
        int pre = j;
        for(;j <= x;) {
//            printf("test i==%d j==%d c[j]==%d\n",i,j,c[j]);
            if(c[j] > 0) {
                c[j] = min(c[j] - 1, a[i]);
                ok = false;
                j++;
                if(j == x + 1) j = 1;
                break;
            }
            j++;
            if(j == x + 1) j = 1;
            if(j == pre) break;
        }
        if(ok) return false;
    }
    return true;
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    sort(a + 1, a + 1 + n, cmp);
    int L = 1, R = n;
    int ans = 0;
//    printf("test %d\n",check(1));
    while(L <= R) {
        int mid = (L + R) >> 1;
//        printf("test %d %d %d\n", L, R, mid);
        if(check(mid)) {
            R = mid - 1;
            ans = mid;
        }
        else L = mid + 1;
    }
    printf("%d\n", ans);
    return 0;
}
View Code

D. Fox and Minimal path

    题意:最多用1000个点,构造一个从1到2有k(1e9)条最短路的图

    思路:把k进行二进制拆分,然后先把最大的2^x次方的路画出来,然后在画一条等长的路,把中间的2^x次方连起来

    代码:

#include <bits/stdc++.h>
using namespace std;

int mp[1007][1007];
int a[57];

int main()
{
    int k;
    scanf("%d", &k);
    int cnt = 0;
    while(k) {
        a[cnt++] = k & 1;
        k >>= 1;
    }
    int now = 3;
    mp[1][3] = mp[3][1] = 1;

    for(int i = 0; i < cnt - 1; i++) {
        mp[now][now + 1] = 1;
        mp[now + 1][now] = 1;
        mp[now][now + 2] = 1;
        mp[now + 2][now] = 1;
        mp[now + 1][now + 3] = 1;
        mp[now + 3][now + 1] = 1;
        mp[now + 2][now + 3] = 1;
        mp[now + 3][now + 2] = 1;
        now += 3;
    }
    int res = now + 1;
    mp[2][now] = mp[now][2] = 1;
    for(int i = 0; i < (cnt - 2) * 2; i++, res++) {
        mp[res][res + 1] = 1;
        mp[res + 1][res] = 1;
    }
    mp[res][now] = mp[now][res] = 1;
    int pos = now + 1;
    now = res;
    int as = 1;
    for(int i = 0; i < cnt; i++) {
        if(a[i]) {
            mp[as * 3][pos] = 1;
            mp[pos][as * 3] = 1;
        }
        as ++;
        pos += 2;
    }
    printf("%d\n",now);
    for(int i = 1; i <= now; i++) {
        for(int j = 1; j <= now; j++) {
            if(mp[i][j])printf("Y");
            else printf("N");
        }
        puts("");
    }
    return 0;
}
View Code

E. Fox and Card Game

    题意:有n(100)堆牌,每堆的牌的数量为s(100),每张牌上都有一个分值,A每次只能从一堆的最上面拿,B只能从一堆的最下面拿,A先手,AB都是绝顶聪明的,问最后AB各拿了多少分

    思路:因为AB都是决定聪明的,所以对于一堆偶数的牌,每个人都拿一半,然后只剩下奇数的牌,对于中间的那张牌排序,轮流那就可以

    代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 105;
int a[maxn];
int stk[maxn], top;
int n;
bool cmp(int x, int y)
{
    return x > y;
}
int main()
{
    scanf("%d", &n);
    int ansx = 0, ansy = 0;
    for(int i = 1; i <= n; i++) {
        int op;
        scanf("%d", &op);
        for(int i = 1; i <= op; i++) {
            scanf("%d", &a[i]);
        }
        int up = op / 2;
        for(int j = 1; j <= up; j++) {
            ansx += a[j];
            ansy += a[op - j + 1];
        }
        if(op & 1) stk[++top] = a[up + 1];
    }
    sort(stk + 1, stk + 1 + n, cmp);
    for(int i = 1; i <= top; i++) {
        if(i & 1) ansx += stk[i];
        else ansy += stk[i];
    }
    printf("%d %d\n", ansx, ansy);
    return 0;
}
View Code

 

posted @ 2019-02-28 13:22  啦啦啦天啦噜  阅读(151)  评论(0编辑  收藏  举报