【CF】codeforces1301E_前缀和_论如何对CF的机器抱有信心

题面

codeforces1301E

题解

就只要想到\(O(n^3)\)的做法,大胆写就能过。

因为你分析一下,这个做法好像常数小得要死?

代码

#include<bits/stdc++.h>
#define LL long long
#define MAXN 500
using namespace std;
template<typename T>void Read(T &cn)
{
    char c;int sig = 1;
    while(!isdigit(c = getchar()))if(c == '-')sig = -1; cn = c-48;
    while(isdigit(c = getchar()))cn = cn*10+c-48; cn*=sig;
}
template<typename T>void Write(T cn)
{
    if(cn < 0) {putchar('-'); cn = 0-cn; }
    int wei = 0; T cm = 0; int cx = cn%10; cn/=10;
    while(cn)cm = cm*10+cn%10,cn/=10,wei++;
    while(wei--)putchar(cm%10+48),cm/=10;
    putchar(cx+48);
}
int f[MAXN/2+1][MAXN+1][MAXN+1];
int n,m,q;
int a[MAXN+1][MAXN+1];
int b[MAXN+1][MAXN+1];
int jian_c(int cn, int cm, int cx)
{
    if(a[cn-cx+1][cm-cx+1] != 'R' || b[cn-cx+1][cm-cx+1] != cx) return 0;
    if(a[cn-cx+1][cm+1] != 'G' || b[cn-cx+1][cm+1] != cx) return 0;
    if(a[cn+1][cm-cx+1] != 'Y' || b[cn+1][cm-cx+1] != cx) return 0;
    if(a[cn+1][cm+1] != 'B' || b[cn+1][cm+1] < cx) return 0;
    return 1;
}
void jian(int cn, int cm)
{
    int lin = min(min(cn,cm),min(n-cn,m-cm));
    for(int i = 1;i<=lin;i++) {if(!jian_c(cn,cm,i)) return; f[i][cn-i+1][cm-i+1] = 1; }
}
void yuchu()
{
    for(int i = 1;i<=n;i++) b[i][m] = 1;
    for(int i = 1;i<=m;i++) b[n][i] = 1;
    for(int i = n-1;i>=1;i--) for(int j = m-1;j>=1;j--)
    {
        if(a[i][j] == a[i+1][j+1] && a[i][j] == a[i+1][j] && a[i][j] == a[i][j+1]) b[i][j] = 1+min(min(b[i+1][j],b[i][j+1]),b[i+1][j+1]);
        else b[i][j] = 1;
    }
}
int suan(int cn,int cx1,int cy1,int cx2,int cy2) {return f[cn][cx2][cy2] - f[cn][cx2][cy1] - f[cn][cx1][cy2] + f[cn][cx1][cy1]; }
int main()
{
    Read(n); Read(m); Read(q);
    for(int i = 1;i<=n;i++)
    {
        while(!isalpha(a[i][1] = getchar()));
        for(int j = 2;j<=m;j++) a[i][j] = getchar();
    }
    yuchu();
    for(int i = 1;i<=n;i++) for(int j = 1;j<=m;j++) jian(i,j);
    for(int ij = 1;ij<=n/2;ij++) for(int i = 1;i<=n;i++) for(int j = 1;j<=m;j++) f[ij][i][j] = f[ij][i-1][j] + f[ij][i][j-1] - f[ij][i-1][j-1] + f[ij][i][j];
    for(int i = 1;i<=q;i++)
    {
        int bx1,by1,bx2,by2; Read(bx1); Read(by1); Read(bx2); Read(by2);
        int ans = 0; int lin = (min(bx2-bx1,by2-by1)+1)/2;
        for(int j = lin;j>=1;j--) if(suan(j,bx1-1,by1-1,bx2-j*2+1,by2-j*2+1)) {ans = 4*j*j; break; }
        Write(ans); puts("");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/czyarl/p/12333341.html