Codeforces Round #184 (Div.2)

这次真的很挫,写了三题竟然只过了一题,cf的数据强是一方面,再者也发现自己写代码时的一些细节部分没有注意,过来改了昨天两天代码都很快AC了。

A.Strange Addition

这题只需要处理几种情况就可以了,100和0必须取,其他如果同时出现X0和X这样的数就取两个,否则XX、X、X0取中间任意一个。

代码如下:

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL Mod= 1e9+7;

int N, num[105];
int vis[105];

int a, b, c;
int h, z;
int first;
// a  1 - 9
// b  10 - 90
// c  11 - 99

void output(int x) {
    if (first) {
        first = 0;
        printf("%d", x);    
    } else {
        printf(" %d", x);   
    }
}

void solve() {
    int cnt = 0;
    if (~h) ++cnt;
    if (~z) ++cnt;
    if (~a && ~b) {
        printf("%d\n", cnt+2);
        if (~h) output(h);
        if (~z) output(z);
        output(a), output(b);
        puts("");
        return;
    } else {
        if (~a) {
            printf("%d\n", cnt+1);
            if (~h) output(h);
            if (~z) output(z);
            output(a);
        } else if (~b) {
            printf("%d\n", cnt+1);
            if (~h) output(h);
            if (~z) output(z);
            output(b);
        } else if (~c){
            printf("%d\n", cnt+1);
            if (~h) output(h);
            if (~z) output(z);
            output(c);
        } else {
            printf("%d\n", cnt);
            if (~h) output(h);
            if (~z) output(z);
        }
    }
    puts("");
}

int main()
{
    int cnt;
    while (scanf("%d", &N) != EOF) {
        h = z = -1;
        a = b = c = -1;
        first = 1;
        int flag10 = 0, flag = 0;
        for (int i = 0; i < N; ++i) {
            scanf("%d", &num[i]);
            if (num[i] == 100) {
                h = 100;
            } else if (num[i] == 0){
                z = 0;
            } else {
                if (num[i] < 10) a = num[i];
                else if (num[i] % 10 == 0) b = num[i];
                else c = num[i];
            }
        }
        solve();
    }
    return 0;
}
View Code

 

B.Continued Fractions

每次把连分数的整数部分减掉,然后两边同时取倒数。我使用了long double来处理。

代码如下:

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL Mod= 1e9+7;
const long double eps = 1e-8;

int sign(long double x) {
    return (x < -eps) ? -1 : (x > eps);
}

struct FENSHU {
    LL a, b;
    void swap() {
        LL t = a;
        a = b, b = t;   
    }
    bool sub(LL x) {
        long double t = (long double)(1.0)*a/b;
        long double y = (long double)(1.0)*x;
        if (sign(t-y) >= 0) {
            a -= b*x;
            return true;
        }
        return false;
    }
    void show() {
        printf("%I64d/%I64d\n", a, b);
    }
}NUM;

LL seq[105];

int main()
{
    LL n;
    while (scanf("%I64d %I64d", &NUM.a, &NUM.b) != EOF) {
        scanf("%I64d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%I64d", &seq[i]);
        }
        int flag = true;
        for (int i = 1; i <= n; ++i) {
            if (!NUM.sub(seq[i])) {
                flag = false;
            }
            else {
                NUM.swap();
            }
              
        }
        if (!flag || NUM.b) puts("NO");
        else puts("YES");
    }   
    return 0;
}
View Code

 

C.Ivan and Powers of Two

一个暴力的方法是高精度模拟2进制相加,最后查看最低位到最高位有多少个位置为0即可,但很可惜,这题的数据范围有点大。由于最多只有10^5个数,因此可以得知连续的这么多个数相加,不会超过20位的2进制位,因此我的想法是把这些数按照某个数指数小于等于它20以内进行分组,然后再一个一个组的求解。

代码入下:

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL Mod= 1e9+7;

int arr[100005];
int N;
int path[100005];
int ret;

int cal(int k) {
    int base = path[0];
    int bit[50] = {0};
    for (int i = 0; i < k; ++i) {
        path[i] -= base;
        bit[path[i]]++;
    }
//  for (int i = 0; i < 6; ++i) {
//      printf("bit[%d] = %d\n", i, bit[i]);
//  }
    for (int i = 0; i < 50; ++i) {
        int c = bit[i] / 2;
        bit[i+1] += c;
        bit[i] %= 2;    
    }
    int p = 49;
    while (!bit[p]) --p;
    for (int i = 0; i < p; ++i) {
        if (!bit[i]) ++ret; 
    }
    return p+base;
}


int main( )
{
    int x;
    while (scanf("%d", &N) != EOF) {
        memset(arr, 0, sizeof (arr));
        ret = 0;
        for (int i = 0; i < N; ++i) {
            scanf("%d", &arr[i]);
        }
        if (N == 1) {
            printf("%d\n", arr[0]);
        } else {
            ret += arr[0];
            path[0] = arr[0];
            int k = 1, base = arr[0];
            for (int i = 1; i < N; ++i) {
                if (arr[i]-base > 20) {
                    int p = cal(k);
                    ret += arr[i]-p-1;
                    path[0] = arr[i];
                    base = arr[i];
                    k = 1;
                } else {
                    path[k++] = arr[i];
                }
            }
            cal(k);
            printf("%d\n", ret);
        }
    }
    return 0;
}
View Code

 

未完...

posted @ 2013-05-20 09:11  沐阳  阅读(291)  评论(0编辑  收藏  举报