zoukankan      html  css  js  c++  java
  • CCPC 长春 J

    https://vjudge.net/problem/Gym-102832J

    J - Abstract Painting

    题意

    在一个平面上画圆,要求如下:

    • 圆的半径(rin{1,2,3,4,5})

    • 圆心在x轴上

    • 圆上所有的点的横坐标(xin[0,n])

    • 任意两个圆只能有一个交点(可相切,不可相交).

    给定n,和一些必须存在的圆。

    问平面上最后的情况会有多少种?

    题解

    假设圆a与x轴的交点为((l_a,0),(r_a,0))

    假设圆b与x轴的交点为((l_b,0),(r_b,0))

    要使得两个圆有交点,当且仅当(l_a< l_b < r_a);

    从左至右枚举每个点的情况,因为半径有5种可能,所以有2^5种情况,

    为了便于统计,枚举时,在(i)枚举的为(r_b=i)的圆。

    然后为了避免两个圆相交,需要记录([i-10,i-1])这一段的情况,

    对于(jin[i-10,i-1]),记录的值为1表示已经画过一个圆a,满足(l_a< j < r_a),因此不能有圆与x轴的左交点为((j,0)).

    (dp[i][j])表示第i位,([i-9,i])的情况对应二进制数值为(j)

    在提前预处理好(2^5*2^{10})种转移是否合法,和转移之后的值。

    另外对于(i<10)时要特殊判断,因为要求(l_ageq0)

    设置条件限制在(2^5)种的放置圆的方案即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e3 + 5, M = (1 << 10) + 5, T = (1 << 5) + 5;
    const int mod = 1e9 + 7;
    int n;
    int existCircle[N];
    int dp[N][M];
    bool sf[M][T];
    int val[M][T];
    string TransBit(int val)
    {
        string s = "";
        for (int i = 0; i < 10; ++i)
            if (val >> i & 1)
                s.push_back('1');
            else
                s.push_back('0');
        return s;
    }
    int main()
    {
        freopen("j.in", "r", stdin);
        ios::sync_with_stdio(false);
        int n, k;
        cin >> n >> k;
        for (int i = 1; i <= k; ++i)
        {
            int c, r;
            cin >> c >> r;
            existCircle[c + r] ^= 1 << (r - 1);
        }
        for (int i = 0; i < (1 << 10); ++i)
            for (int j = 0; j < (1 << 5); ++j)
            {
                sf[i][j] = 1;
                int nextVal = i;
                for (int l = 1; l <= 5; ++l)
                    if (j >> (l - 1) & 1)
                    {
                        if (i >> (10 - 2 * l) & 1)
                        {
                            sf[i][j] = 0;
                            break;
                        }
                        for (int o = 11 - 2 * l; o <= 9; ++o)
                            nextVal |= 1 << o;
                    }
                val[i][j] = nextVal >> 1;
                //    cout << '(' << i << ',' << j << ") ";
                //    cout << sf[i][j] << ' ' << TransBit(nextVal) << endl;
            }
        dp[0][0] = 1;
        for (int i = 1; i <= n; ++i)
        {
            int limitVal = 0;
            for(int j=1;j<=5;++j)
                if(i-2*j<0)
                    limitVal += 1 << (j-1);
            for (int j = 0; j < (1 << 10); ++j)
                for (int l = 0; l < (1 << 5); ++l)
                    if ((l & existCircle[i]) == existCircle[i] && sf[j][l] && (l & limitVal) == 0)
                    {
    
                        dp[i][val[j][l]] += dp[i - 1][j];
                        dp[i][val[j][l]] %= mod;
                    }
        }
        int ans = 0;
        for (int j = 0; j < (1 << 10); ++j)
            ans += dp[n][j], ans %= mod;
        cout << ans;
        return 0;
    }
    
    
  • 相关阅读:
    Introduction to XQuery in SQL Server 2005
    [译]Cassandra 架构简述
    冬日绘版实录
    网页实现串口TCP数据通讯的两种方案
    (转)感知哈希算法
    CoreParking
    单线程扫描电脑所有文件与并行计算扫描电脑所有文件所用时间?
    强名称程序集
    一些题(六)
    一些题(五)
  • 原文地址:https://www.cnblogs.com/bzmd/p/14289790.html
Copyright © 2011-2022 走看看