• Codeforces Round #341 (Div. 2)


    在家都变的懒惰了,好久没写题解了,补补CF

    模拟 A - Wet Shark and Odd and Even

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    
    int main(void)	{
    	std::vector<int> vec;
    	int n;	scanf ("%d", &n);
    	ll sum = 0;
    	for (int x, i=1; i<=n; ++i)	{
    		scanf ("%d", &x);
    		sum += x;
    		if (x & 1)	vec.push_back (x);
    	}
    	std::sort (vec.begin (), vec.end ());
    	int sz = vec.size ();
    	if (sz > 0 && (sz & 1))	sum -= vec[0];
    	printf ("%I64d
    ", sum);
    
    	return 0;
    }
    

    暴力 B - Wet Shark and Bishops

    开始想错了,当成斜率相等的。还好1000范围不大,统计矩阵每条对角线上的个数加点小优化就过了,代码丑。。。

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 2e5 + 5;
    bool vis[2][1005][1005];
    int b[1005][1005];
    std::pair<int, int> a[N];
    
    ll cal(int x)	{
    	return 1ll * x * (x - 1) / 2;
    }
    int get_num1(int x, int y)	{
    	int xx = x, yy = y;
    	int ret = 0;
    	while (xx >= 1 && yy >= 1)	{
    		if (b[xx][yy])	ret++, vis[1][xx][yy] = true;
    		xx--;	yy--;
    	}
    	xx = x + 1, yy = y + 1;
    	while (xx <= 1000 && yy <= 1000)	{
    		if (b[xx][yy])	ret++, vis[1][xx][yy] = true;
    		xx++;	yy++;
    	}
    	return ret;
    }
    
    int get_num0(int x, int y)	{
    	int xx = x, yy = y;
    	int ret = 0;
    	while (xx <= 1000 && yy >= 1)	{
    		if (b[xx][yy])	ret++, vis[0][xx][yy] = true;
    		xx++;	yy--;
    	}
    	xx = x - 1, yy = y + 1;
    	while (xx >= 1 && yy <= 1000)	{
    		if (b[xx][yy])	ret++, vis[0][xx][yy] = true;
    		xx--;	yy++;
    	}
    	return ret;
    }
    
    int main(void)	{
    	int n;	scanf ("%d", &n);
    	for (int i=0; i<n; ++i)	{
    		scanf ("%d%d", &a[i].first, &a[i].second);
    		b[a[i].first][a[i].second] = 1;
    	}
    	ll ans = 0;
    	for (int i=0; i<n; ++i)	{
    		int x = a[i].first, y = a[i].second;
    		if (!vis[0][x][y])	{
    			ans += cal (get_num0 (x, y));
    			vis[0][x][y] = true;
    		}
    		if (!vis[1][x][y])	{
    			ans += cal (get_num1 (x, y));
    			vis[1][x][y] = true;
    		}
    	}
    	printf ("%I64d
    ", ans);
    
    	return 0;
    }
    

    期望 C - Wet Shark and Flowers

    E = sum (1000 * 乘积是p的倍数的概率)

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 1e5 + 5;
    const int EPS = 1e-8;
    int l[N], r[N];
    double pos[N];
    
    int main(void)	{
    	int n, p;	scanf ("%d%d", &n, &p);
    	for (int i=1; i<=n; ++i)	{
    		scanf ("%d%d", &l[i], &r[i]);
    		pos[i] = 1.0 * (r[i] / p - ((l[i]-1) / p)) / (r[i] - l[i] + 1);
    	}
    	l[0] = l[n], r[0] = r[n], pos[0] = pos[n];
    	double ans = 0;
    	for (int i=0; i<=n; ++i)	{
    		if (i < n)	ans += pos[i] * 1.0 + (1.0 - pos[i]) * pos[i+1];
    		if (i > 0)	ans += pos[i] * 1.0 + (1.0 - pos[i]) * pos[i-1];
    	}
    	ans *= 1000;
    	printf ("%.8f
    ", ans);
    
    	return 0;
    }
    

    数学(浮点) D - Rat Kwesh and Cheese

    都取log,用long double,精度逆天!powl (): pow的long double版

    C语言里对float类型数据的表示范围为-3.4*10^38~+3.4*10^38。double为-1.7*10^-308~1.7*10^308,long double为-1.2*10^-4932~1.2*10^4932.

    类型

    比特(位)数

    有效数字

    数值范围

    float

    32

    6~7

    -3.4*10^38~+3.4*10^38

    double

    64

    15~16

    -1.7*10^-308~1.7*10^308

    long double

    128/

    18~19

    -1.2*10^-4932~1.2*10^4932

     

     

     

     

     

     

    究竟如何计算该范围,分析如下:

    对于单精度浮点数(float)来说,符号位一位,指数位8位,尾数23位。指数能够表示的指数范围为-128~127。尾数为23位。

    #include <bits/stdc++.h>
    
    std::string ans[12] = {
    "x^y^z", "x^z^y", "(x^y)^z", "(x^z)^y", "y^x^z", "y^z^x",
    "(y^x)^z", "(y^z)^x", "z^x^y", "z^y^x", "(z^x)^y", "(z^y)^x"
    };
    
    typedef long double ldouble;
    const double EPS = 1e-10;
    ldouble best;
    int id;
    
    bool better(ldouble val)	{
    	if (fabs (val - best) < EPS)	return false;
    	else if (best < val)	{
    		best = val;
    		return true;
    	}
    	return false;
    }
    
    void try2(ldouble x, ldouble y, ldouble z, int pos)	{
    	//(x ^ y) ^ z
    	ldouble val = z * y * log (x);
    	if (better (val))	id = pos;
    }
    
    void try1(ldouble x, ldouble y, ldouble z, int pos)	{
    	//x ^ y ^ z
    	ldouble val = powl (y, z) * log (x);
    	if (better (val))	id = pos;
    }
    
    int main(void)	{
    	ldouble x, y, z;	std::cin >> x >> y >> z;
    	best = -1e12;	id = -1;
    	try1 (x, y, z, 0);
    	try1 (x, z, y, 1);
    	try2 (x, y, z, 2);
    	try2 (x, z, y, 3);
    	try1 (y, x, z, 4);
    	try1 (y, z, x, 5);
    	try2 (y, x, z, 6);
    	try2 (y, z, x, 7);
    	try1 (z, x, y, 8);
    	try1 (z, y, x, 9);
    	try2 (z, x, y, 10);
    	try2 (z, y, x, 11);
    	std::cout << ans[id] << '
    ';
    
    	return 0;
    }
    

     

    数位DP(矩阵快速幂优化) E - Wet Shark and Blocks

    题意:b组相同的n个数字,每组选择一个数字合并起来%x == k的方案数。

    分析:dp思路,dp[i][(j*10+t)%x] += dp[i-1][j]。但是b太大了选择用矩阵快速幂优化,构造矩阵m[i][j]表示从i到j的方案数,答案就是m[0][k],那么base矩阵就是小于x的某个数字转移到根据给出n个数字转移到另一个数字y的方案数。

    UPD:

    寒假排位赛出了这题,又不会做。

    构造x*x大小的矩阵,m[i][j]表示从i(%x)到j(%x)的方案数,状态转移用矩阵乘法:i->j1,j2,j3...->k => i->k

     

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef vector<ll> Vec;
    typedef vector<Vec> Mat;
    const int N = 5e4 + 5;
    const int MOD = 1e9 + 7;
    int cnt[10];
    int n, b, k, x;
    
    void add_mod(ll &a, ll b) {
        a += b;
        if (a >= MOD) a -= MOD;
    }
    
    Mat matrix_mul(const Mat &A, const Mat &B) {
        Mat ret(A.size(), Vec(B[0].size()));
        for (int i=0; i<A.size(); ++i)
            for (int j=0; j<A[0].size(); ++j) if (A[i][j])
                for (int k=0; k<B[0].size(); ++k) if (B[j][k])
                    add_mod(ret[i][k], A[i][j]*B[j][k]%MOD);
        return ret;
    }
    
    Mat matrix_pow(Mat X, int n) {
        Mat ret(X.size(), Vec(X.size()));
        for (int i=0; i<X.size(); ++i) ret[i][i] = 1;
        for (; n; n>>=1) {
            if (n & 1) ret = matrix_mul(ret, X);
            X = matrix_mul(X, X);
        }
        return ret;
    }
    
    int main() {
        scanf("%d%d%d%d", &n, &b, &k, &x);
        for (int i=1; i<=n; ++i) {
            int d;
            scanf("%d", &d);
            cnt[d]++;
        }
        Mat ans(100, Vec(100));
        for (int i=0; i<x; ++i) {
            for (int j=1; j<=9; ++j) {
                ans[i][(i*10+j)%x] += cnt[j];
            }
        }
        ans = matrix_pow(ans, b);
        printf("%I64d
    ", ans[0][k]);
        return 0;
    }

     

      

     

    编译人生,运行世界!
  • 相关阅读:
    mysql常用的语句示例
    node的模块机制
    mongodb的一些技术点
    php的权限设置流程
    linux常用命令大全
    通过centos7.2搭建个人博客--------------服务器篇
    详解vuex时光机
    详解位运算符的一些特点
    一位资深程序员大牛给予Java初学者的学习路线建议
    JDBC
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5176114.html
Copyright © 2020-2023  润新知