zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 199 题解

    本场链接:AtCoder Beginner Contest 199

    A - Square Inequality

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    
    int main()
    {
    	Angel_Dust;
    	int a,b,c;cin >> a >> b >> c;
    	if(a * a + b * b < c * c)	cout << "Yes
    ";
    	else cout << "No
    ";
        return 0;
    }
    
    

    B - Intersection

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 105;
    int a[N],b[N];
    
    int main()
    {
    	int n;scanf("%d",&n);
    	forn(i,1,n)	scanf("%d",&a[i]);
    	forn(i,1,n)	scanf("%d",&b[i]);
    
    	int res = 0;
    	forn(x,1,1000)
    	{
    		bool ok = 1;
    		forn(i,1,n)
    		{
    			if(a[i] <= x && x <= b[i])	continue;
    			ok = 0;
    			break;
    		}
    		if(ok)	++res;
    	}
    
    	printf("%d
    ",res);
        return 0;
    }
    
    

    C - IPFL

    为了实现操作2,不妨将原来的整个字符串切割成S1,S2。对于操作2,直接swap(s1,s2)即可。对于操作1,讨论位置在哪个字符串内再进行swap即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    
    int main()
    {
    	Angel_Dust;
    	int n;cin >> n;
    	string s1,s2;cin >> s1;
    	s2 = s1.substr(n,n);
    	s1.resize(n);
    
    	int q;cin >> q;
    	while(q--)
    	{
    		int t,a,b;cin >> t >> a >> b;
    		--a;--b;
    		if(t == 1)
    		{
    			if(a < n && b < n)	swap(s1[a],s1[b]);
    			if(a < n && b >= n)	swap(s1[a],s2[b - n]);
    			if(a >= n && b < n)	swap(s2[a - n],s1[b]);
    			if(a >= n && b >= n)	swap(s2[a - n],s2[b - n]);
    		}
    		else	swap(s1,s2);
    	}
    
    	cout << s1 << s2 << endl;
        return 0;
    }
    
    

    D - RGB Coloring 2

    最粗暴的想法:直接枚举每个点的颜色,再通过图判断方案是否合法,复杂度(O(3^n))显然是不可以接受的。

    如果这个图本身是联通的,那么如果某个点的颜色被确定了之后,与他相邻的点事实上只有(2)个选择,进而可以推出实际上方案数是(O(3*2^{n-1}))的,复杂度就可以承受了。枚举每个点的颜色判断是否合法即可。

    那么如果图不连通怎么办?对于每个独立块求完答案后乘法原理合并即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 22,M = N * N;
    vector<int> E[N];
    int col[N],n,m;
    ll res;
    
    
    void dfs(int u,ll ans)
    {
    	if(u == n + 1)	res += ans;
    	else if(E[u].empty())	dfs(u + 1,ans * 3);
    	else
    	{
    		forn(_,1,3)
    		{
    			bool ok = 1;
    			for(auto& v : E[u])
    				if(col[v] == _)
    					ok = 0;
    			if(ok)
    			{
    				col[u] = _;
    				dfs(u + 1,ans);
    				col[u] = 0;
    			}
    		}
    	}
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	forn(_,1,m)
    	{
    		int u,v;scanf("%d%d",&u,&v);
    		E[u].push_back(v);E[v].push_back(u);
    	}
    
    	dfs(1,1);
    
    	printf("%lld
    ",res);
        return 0;
    }
    
    

    E - Permutation

    注意到如果我们把排列的构造换成某种二元关系(可以用0/1表达)的话,这个题可以状压表达当前的局面。

    • 状态:(f[S])表示当前选择的数的集合是S的前提下,满足所有(x_i leq |S|)的约束条件的方案数。
    • 入口:(f[0] = 1)显然
    • 转移:考虑枚举新加入的数(x),那么首先(x)不属于S集合,其次在加入(x)之后会引入所有(x_i = |s|+1)的约数条件,直接判断这些新加入的约束条件是否仍然满足即可。
    • 出口:(f[(1 << n) - 1])所有元素都选择上的情况。
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    
    const int N = 18;
    struct Node
    {
        int x,y,z;
    };
    ll f[1 << N];
    vector<Node> E[N];
    
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        f[0] = 1;
        forn(i,1,m)
        {
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            E[x].push_back({x,y,z});
        }
    
        forn(S,0,(1 << n) - 1)
        {
            forn(x,0,n - 1)
            {
                if(S >> x & 1)  continue;
                int sz = 1,ok = 1;
                forn(j,0,n - 1) if(S >> j & 1)  ++sz;
                for(auto& lim : E[sz])
                {
                    int cnt = 0;
                    if(x + 1 <= lim.y)  ++cnt;
                    forn(j,0,n - 1) if((S >> j & 1) && j + 1 <= lim.y)  ++cnt;
                    if(cnt > lim.z)
                    {
                        ok = 0;
                        break;
                    }
                }
                if(!ok) continue;
                f[S | (1 << x)] += f[S];
            }
        }
    
        printf("%lld
    ",f[(1 << n) - 1]);
        return 0;
    }
    
    

    F - Graph Smoothing

    形式非常套路的一道题,看到数据范围就可以猜到矩阵快速幂了。

    首先考虑一个暴力的DP

    • 状态:(f[i][k])表示(i)点权期望在(k)次操作之后的取值。
    • 入口:(f[i][0] = a[i])
    • 转移:每次随机选择一条边,那么只有两种情况:要么以(1/m)的概率选择上一条边与(i)相连,另一点记为(v),那么之后两者会取平均。要么就((m - deg_i) / m)的概率选择一条不与(i)相连的边,此后权值不变。记(S_i)为所有与(i)点有一条边直接相连的点集,那么转移方程(f[i][k] = (1/m)sumlimits_{v in S_i}(f[i][k - 1] + f[v][k - 1]) / 2 + ((m - deg_i)/m)f[i][k - 1])合并一下项可以得到:(f[i][k] = 1 / (2*m) sumlimits_{v in S_i}f[v][k - 1] + (2 * m - deg_i) / (2 * m) f[i][k - 1])
    • 出口:(f[i][k])

    考虑矩阵快速幂把(k)优化掉,保留(f[i])表示(i)点的期望权值。

    考虑构造系数矩阵:如果((u,v))之间有一条边直接相连,在一次转移的时候(f[u])会向(f[v])产生(f[u] / (2 * m))的贡献,则让系数矩阵(B[v][u] = 1 / (2 * m)),反之亦然。对于每个点自身的贡献:对应的直接让(B[i][i] = (2 * m - deg_i) / (2 * m))

    最后答案就是(f * B^k)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define forn(i,x,n) for(int i = x;i <= n;++i)
    typedef pair<int,int> pii;
    #define forr(i,x,n) for(int i = n;i >= x;--i)
    #define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
    #define x first
    #define y second
    
    const int N = 105,MOD = 1e9+7;
    pii edges[N * N];
    int deg[N];
    
    struct Mat
    {
        int c[N][N];
        Mat()
        {
            memset(c,0,sizeof c);
        }
        Mat operator*(const Mat& r) const
        {
            Mat res;
            forn(i,1,N - 1) forn(j,1,N - 1) forn(k,1,N - 1) res.c[i][j] = (res.c[i][j] + 1ll*c[i][k] * r.c[k][j] % MOD) % MOD;
            return res;
        }
        void operator*(int r) 
        {
            forn(i,1,N - 1) forn(j,1,N - 1) c[i][j] = 1ll*c[i][j] * r % MOD;
        }
    };
    
    Mat qpow(Mat a,int b,int MOD)
    {
        Mat res;forn(i,1,N - 1) res.c[i][i] = 1;
        while(b)
        {
            if(b & 1)   res = res * a;
            a = a * a;
            b >>= 1;
        }
        return res;
    }
    
    int qpow(int a,int b,int MOD)
    {
        int res = 1;
        while(b)
        {
            if(b & 1)   res = 1ll * res * a % MOD;
            a = 1ll * a * a % MOD;
            b >>= 1;
        }
        return res;
    }
    
    int main()
    {
        int n,m,k;scanf("%d%d%d",&n,&m,&k);
        Mat f,B;forn(i,1,n)   scanf("%d",&f.c[1][i]);
    
        forn(i,1,m)
        {
            int u,v;scanf("%d%d",&u,&v);
            ++deg[u];++deg[v];
            edges[i] = {u,v};
        }
    
        int m_2fact = qpow(m * 2,MOD - 2,MOD);
        
        forn(i,1,m)
        {
            int u = edges[i].x,v = edges[i].y;
            B.c[u][v] = m_2fact;
            B.c[v][u] = m_2fact;
        }
    
        forn(i,1,n) B.c[i][i] = (2 * m - deg[i]) * 1ll * m_2fact % MOD;
        
    
        B = qpow(B,k,MOD);
        f = f * B;
        forn(i,1,n) printf("%d
    ",f.c[1][i]);
        return 0;
    }
    
    
  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/HotPants/p/14706700.html
Copyright © 2011-2022 走看看