Codeforces Round 341 div2

来源:互联网 发布:人工智能仿生眼 编辑:程序博客网 时间:2024/06/07 03:16

Codeforces Round 341 div2
题目链接:
通过数:3(一题被叉一题未看懂)
Standing:310/5929
Rating change: 1862-1869
比赛总结:
题目都属于可以理解可以做的范围,原来以为要变色了……

A:
所有数任意选,求最大的和且和为偶数的值。

#include <cstdio>#include <cmath>#include <cstring>#include <cstdlib>#include <iostream>#include <string>#include <algorithm>using namespace std;#define LL long longconst int MAXN = 100000 + 5;LL a[MAXN];int main(){    int n;    while(scanf("%d", &n) != EOF){        int cnt = 0;        LL sum = 0;        for(int i = 0 ; i < n ; i++){            LL u;            scanf("%I64d", &u);            if(u % 2 == 1) a[cnt++] = u;            sum += u;        }        if(sum % 2 == 0) printf("%I64d\n", sum);        else{            sort(a, a + cnt);            printf("%I64d\n", sum - a[0]);        }    }    return 0;}

B:
坐标,发现就是y=x+b和y=-x+b上,所以直接换了个坐标系。
好像有更复杂的写法,然而不想补了

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <algorithm>#include <iostream>using namespace std;#define LL long longconst int MAXN = 4000 + 100;int c1[MAXN], c2[MAXN];int main(){    int n;    while(scanf("%d", &n) != EOF){        memset(c1, 0, sizeof(c1));        memset(c2, 0, sizeof(c2));        LL ans = 0;        for(int i = 0 ; i < n ; i++){            int x, y;            scanf("%d%d", &x, &y);            int u = x - y + 1000;            int v = x + y + 1000;            ans += c1[u]; c1[u]++;            ans += c2[v]; c2[v]++;        }        printf("%I64d\n", ans);    }    return 0;}

C:
刚开始没看懂题,看懂后秒过了。求相邻一对取数能取到p的倍数的概率,这还用想吗

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <algorithm>#include <iostream>using namespace std;const int MAXN = 100000 + 5;int l[MAXN], r[MAXN];double lv[MAXN];double dp[MAXN][3];int n, p;double cal(int i){    return 1 - (1 - lv[i - 1]) * (1 - lv[i]) ;}int main(){    while(scanf("%d%d", &n, &p) != EOF){        for(int i = 1 ; i <= n ; i++){            scanf("%d%d", &l[i], &r[i]);            int u1 = l[i] / p, v1 = l[i] % p;            int u2 = r[i] / p, v2 = r[i] % p;            int temp = u2 - u1;            if(v1 == 0) temp++;            lv[i] = 1.0 * temp / (r[i] - l[i] + 1);        }        l[0] = l[n], r[0] = r[n]; lv[0] = lv[n];        l[n + 1] = l[1], r[n + 1] = r[1]; lv[n + 1] = lv[1];//        for(int i = 0 ; i <= n + 1 ; i++) printf("lv[%d] = %f\n", i, lv[i]);        double ans = 0;        for(int i = 1 ; i <= n ; i++){            ans += cal(i) * 2000;//            printf("cal[%d] = %f\n", i, cal(i));        }//        memset(dp, 0, sizeof(dp));//        for(int i = 1 ; i <= n + 1; i++){//            if(i == 1){//                dp[i][0] = (1 - lv[i]);//                dp[i][1] = lv[i];//            }//            else{//                dp[i][0] = (1 - lv[i]) * (dp[i - 1][1]);//                dp[i][1] = lv[i] * (dp[i - 1][1] + dp[i - 1][0]);//            }//            printf("dp[%d][0] = %f, dp[%d][1] = %f\n", i, dp[i][0], i, dp[i][1]);//        }//        double ans = (dp[n + 1][0] + dp[n + 1][1]) * 1000 * n;        printf("%.6f\n", ans);    }    return 0;}

D:
因为之前写过一个处理这种大数的题,所以得意忘形的开loglog处理就没管了……然而忘记了对数的性质。
笨办法是分类讨论,水办法是long double。
看到一种神做法,把数看成实数,然后排序……贴一下
转侵删
If x > 1, then log(log(x)) is an increasing function, and if x < 1, thenreal(log(log(x))) is a decreasing function, because taking a logarithm of a negative number results in something like this:log( - x) = log( - 1 * x) = log( - 1) + logx = iπ + log(x). (Assuming log(x) is done in base e) Therefore, to compare two numbers by their loglog, you can do something like this:
bool compare (complex x, complex y) {
if (imag(x) == 0 and imag(y) == 0)
return real(x) > real(y);
else if (imag(x) != 0 and imag(y) == 0)
return false;
else if (imag(x) == 0 and imag(y) != 0)
return true;
else if (imag(x) != 0 and imag(y) != 0)
return real(x) < real(y);}

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <algorithm>#include <iostream>#include <string>using namespace std;#define inf (1000000007)double a[20];double cal1(double x, double y, double z){    double ans;    ans = z * log(y) + log(log(x));//    printf("x = %f, y = %f, z = %f\n");//    printf("first part = %f\nsecond part = %f\n", z * log(y), log(log(x)));//    system("pause");//    printf("ans = %f\n", ans);    return ans;}double cal2(double x, double y, double z){    double ans;    ans = log(y) + log(z) + log(log(x));    return ans;}int solve(double x, double y, double z){    for(int i = 1 ; i <= 12 ; i++) a[i] = -inf;    if(x <= 1 && y <= 1 && z <= 1){        double xx = 1.0 / x, yy = 1.0 / y, zz = 1.0 / z;        if(xx != 1){            a[1] = cal1(xx, y, z);            a[2] = cal1(xx, z, y);            a[3] = cal2(xx, y, z);            a[4] = cal2(xx, z, y);        }        if(yy != 1){            a[5] = cal1(yy, x, z);            a[6] = cal1(yy, z, x);            a[7] = cal2(yy, x, z);            a[8] = cal2(yy, z, x);        }        if(zz != 1){            a[9] = cal1(zz, x, y);            a[10] = cal1(zz, y, x);            a[11] = cal2(zz, x, y);            a[12] = cal2(zz, y, x);        }        int re = 1;        double mmax = a[1];        for(int i = 1 ; i <= 12 ; i++){            if(a[i] < mmax) mmax = a[i], re = i;        }        return re;    }    else{        if(x > 1){        a[1] = cal1(x, y, z);        a[2] = cal1(x, z, y);        a[3] = cal2(x, y, z);        a[4] = cal2(x, z, y);        }        if(y > 1){        a[5] = cal1(y, x, z);        a[6] = cal1(y, z, x);        a[7] = cal2(y, x, z);        a[8] = cal2(y, z, x);        }        if(z > 1){        a[9] = cal1(z, x, y);        a[10] = cal1(z, y, x);        a[11] = cal2(z, x, y);        a[12] = cal2(z, y, x);        }    }//    for(int i = 1 ; i <= 12 ; i++)//        printf("%f\n", a[i]);//    printf("\n");    int re = 1;    double mmax = a[1];    for(int i = 1 ; i <= 12 ; i++){        if(a[i] > mmax) mmax = a[i], re = i;    }    return re;}int out[5];void print(int mark){    if(mark == 1) printf("x^y^z\n");    if(mark == 2) printf("x^z^y\n");    if(mark == 3) printf("(x^y)^z\n");    if(mark == 4) printf("(x^z)^y\n");    if(mark == 5) printf("y^x^z\n");    if(mark == 6) printf("y^z^x\n");    if(mark == 7) printf("(y^x)^z\n");    if(mark == 8) printf("(y^z)^x\n");    if(mark == 9) printf("z^x^y\n");    if(mark == 10) printf("z^y^x\n");    if(mark == 11) printf("(z^x)^y\n");    if(mark == 12) printf("(z^y)^x\n");}int main(){//    printf("log(3.4) = %f, loglog(1.1) = %f\n", log(3.4), log(log(1.1)));    double x, y, z;    while(cin >> x >> y >> z){//    x *= 10, y *= 10, z *= 10;//        x *= 1000, y *= 1000, z *= 1000;        int mark = solve(x, y, z);        print(mark);    }//    }    return 0;}

E:
这题改了一天……
题目意思说凑一个b位的数,要求它mod(x)==k。问有几种凑法。
首先按照数位dp思想。设dp[i][j]表示i位余数为j有多少种情况。然后发现这是一个矩阵快速幂,因为dp[i]可以由dp[i-1]得到。
然而那个矩阵怎么表示?因为乘式表示位dp[i-1]*T=dp[i],想到半夜得到的结果是T[i][j]表示当前余数为i、新添加j时得到余数为j的矩阵。T的初始化见代码,解释的意思是刚开始只有0位时,余数不定。然后由于dp[0] = {1,0,0,…0},故输出T[0][k]即可。

#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <algorithm>#include <iostream>using namespace std;#define LL long long#define mod (1000000007)const int MAXN = 100 + 5;struct Matrix{    LL a[MAXN][MAXN];    int len;    Matrix(){memset(a, 0, sizeof(a));}    void init(int _len){        len = _len;        for(int i = 0 ; i < len ; i++){            for(int j = 0 ; j < len ; j++){                if(i == j) a[i][j] = 1;                else a[i][j] = 0;            }        }    }    Matrix operator + (const Matrix &rbs)const{        Matrix res;        res.len = len;        for(int i = 0 ; i < len ; i++)            for(int j = 0 ; j < len ; j++) res.a[i][j] = (a[i][j] + rbs.a[i][j]) % mod;        return res;    }    Matrix operator * (const Matrix &rbs)const{        Matrix res;        res.len = len;        for(int i = 0 ; i < len ; i++){            for(int k = 0 ; k < len ; k++){                for(int j = 0 ; j < len ; j++)                    res.a[i][j] = (res.a[i][j] + a[i][k] * rbs.a[k][j]) % mod;            }        }        return res;    }    void print(){        for(int i = 0 ; i < len ; i++){            for(int j = 0 ; j < len ; j++) printf("%I64d ", a[i][j]);            printf("\n");        }    }};Matrix ppow(Matrix u, int b){    Matrix ans;    ans.init(u.len);    for(int i = b ; i ; i >>= 1){        if(i & 1) ans = (ans * u);        u = (u * u);//        ans.print();//        printf("\n");//        u.print();//        system("pause");    }    return ans;}int n, b, k, x;LL g[MAXN];LL out[MAXN];int main(){    while(scanf("%d%d%d%d", &n, &b, &k, &x) != EOF){        memset(g, 0, sizeof(g));        int u;        while(n--){            scanf("%d", &u);            g[u % x]++;        }        Matrix temp;        temp.len = x;        for(int i = 0 ; i < x ; i++){            for(int j = 0 ; j < x ; j++){                temp.a[i][(10 * i + j) % x] = g[j];            }        }//        temp.print();//        system("pause");//        for(int i = 0 ; i < x ; i++){//            for(int j = 0 ; j < x ; j++) printf("%I64d ", temp.a[i][j]);//            printf("\n");//        }        temp = ppow(temp, b);//        temp.print();//        LL ans = 0;//        for(int i = 0 ; i < x ; i++) ans = (ans + temp.a[k][i]) % mod;//        printf("%I64d\n", ans);//        for(int i = 0 ; i < x ; i++){//            for(int j = 0 ; j < x ; j++) printf("%I64d ", temp.a[i][j]);//            printf("\n");//        }//        memset(out, 0, sizeof(out));//        for(int i = 0 ; i < x ; i++) for(int j = 0 ; j < x ; j++) out[i] = (out[i] + g[j] * temp.a[i][j]) % mod;//        for(int i = 0 ; i < x ; i++) printf("%I64d ", out[i]);//        printf("\n");        printf("%I64d\n", temp.a[k][0]);    }    return 0;}
0 0
原创粉丝点击