zoukankan      html  css  js  c++  java
  • Codeforces 677E Vanya and Balloons

    Vanya and Balloons

    枚举中心去更新答案, 数字过大用log去比较, 斜着的旋转一下坐标, 然后我旋出来好多bug。。。。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 3000 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    int power(int a, int b) {
        int ans = 1;
        while(b) {
            if(b & 1) ans = 1LL * ans * a % mod;
            a = 1LL * a * a % mod; b >>= 1;
        }
        return ans;
    }
    
    int n, a[N][N], b[N][N];
    short row[N][N][2], col[N][N][2];
    short L[N][N], R[N][N], U[N][N], D[N][N];
    bool vis[N][N];
    
    LD lg2 = logl(2), lg3 = logl(3);
    
    bool cmp(const PII& a, const PII& b) {
        return a.fi * lg2 + a.se * lg3 < b.fi * lg2 + b.se * lg3;
    }
    
    inline int calcRow(int i, int l, int r, int op) {
        return row[i][r][op] - row[i][l][op];
    }
    inline int calcCol(int j, int l, int r, int op) {
        return col[j][r][op] - col[j][l][op];
    }
    
    PII calc(int a[N][N], int n) {
        PII ans = mk(0, 0);
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(!a[i][j]) L[i][j] = j, U[i][j] = i;
                else L[i][j] = L[i][j - 1], U[i][j] = U[i - 1][j];
                row[i][j][0] = row[i][j - 1][0] + (a[i][j] == 2);
                row[i][j][1] = row[i][j - 1][1] + (a[i][j] == 3);
                col[j][i][0] = col[j][i - 1][0] + (a[i][j] == 2);
                col[j][i][1] = col[j][i - 1][1] + (a[i][j] == 3);
            }
        }
        for(int i = n; i >= 1; i--) {
            for(int j = n; j >= 1; j--) {
                if(!a[i][j]) R[i][j] = j, D[i][j] = i;
                else {
                    if(j == n) R[i][j] = j + 1;
                    else R[i][j] = R[i][j + 1];
                    if(i == n) D[i][j] = i + 1;
                    else D[i][j] = D[i + 1][j];
                }
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(!a[i][j] || !vis[i][j]) continue;
                int d = min({i - U[i][j], D[i][j] - i, j - L[i][j], R[i][j] - j});
                PII tmp = mk(0, 0);
                tmp.fi += calcRow(i, j - d, j + d - 1, 0);
                tmp.fi += calcCol(j, i - d, i + d - 1, 0);
                tmp.se += calcRow(i, j - d, j + d - 1, 1);
                tmp.se += calcCol(j, i - d, i + d - 1, 1);
                if(a[i][j] == 2) tmp.fi--;
                else if(a[i][j] == 3) tmp.se--;
                if(cmp(ans, tmp)) {
                    ans = tmp;
                }
            }
        }
        return ans;
    }
    
    int main() {
        int mask = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                scanf("%1d", &a[i][j]), vis[i][j] = true, mask |= a[i][j];
        if(!mask) return puts("0"), 0;
        PII ret1 = calc(a, n);
        for(int i = 1; i <= 3 * n; i++)
            for(int j = 1; j <= 3 * n; j++)
                b[i][j] = 1, vis[i][j] = false;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                b[i - j + n][i + j + n] = a[i][j], vis[i - j + n][i + j + n] = true;
        int lx = 1 - 1 + n, ly = 1 + 1 + n;
        int rx = n - n + n, ry = n + n + n;
        int x = (lx + rx) / 2, y = (ly + ry) / 2;
        int d = abs(x - lx) + abs(y - ry);
        for(int i = 1; i <= 3 * n; i++)
            for(int j = 1; j <= 3 * n; j++)
                if(abs(i - x) + abs(j - y) > d)
                    b[i][j] = 0;
        PII ret2 = calc(b, 3 * n);
        if(cmp(ret1, ret2)) {
            printf("%d
    ", 1LL * power(2, ret2.fi) * power(3, ret2.se) % mod);
        } else {
            printf("%d
    ", 1LL * power(2, ret1.fi) * power(3, ret1.se) % mod);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    微软并行编程类库Parallel Extensions初探 Part1 (转)
    一些很酷的.Net技巧(上)
    【Silverlight】Silvelright端获取托管web项目中xap的路劲
    【Silverlight】Silvelright获取web端的xml
    博客开始第一天
    asp.net过滤HTML方法
    程序员应该懂的道理
    生成缩略图
    转:用自定义IHttpModule实现URL重写
    android 之helloword
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10756335.html
Copyright © 2011-2022 走看看