UVA 10593 - Kites

来源:互联网 发布:软件开发企业会计核算 编辑:程序博客网 时间:2024/05/05 18:17

 

Problem E

Kites

Time Limit

4 Seconds

 

The season of flying kites is well ahead. So what? Let us make an inventory for kites. We are given a square shaped sheet of paper. But many parts of this are already porous. Your challenge here is to count the total number of ways to cut a kite of any size from this sheet. By the way, the kite itself can't be porous :-) AND..................it must be either square shaped or diamond shaped.

 
                        x
           x           xxx           xxx           xxx
          xxx         xxxxx          xxx           x.x         x
           x           xxx           xxx           xxx
                        x

In the above figure first three are valid kites but not next two.

 

Input

Input contains an integer n (n ≤ 500), which is the size of the sheet. Then follows n lines each of which has n characters ('x' or '.'). Here the dotted parts resemble the porous parts of the sheet. Input is terminated by end of file.

 

Output

Output is very simple. Only print an integer according to the problem statement for each test case in a new line.

 

Sample Input

Output for Sample Input

4
.xx.
xxxx
.xx.
.x..
3
xxx
xxx
xxx

4

6

 

Problemsetter: Mohammad Sajjad Hossain

Bangladesh University of Engineering and Technology



思路:正方形和菱形分开来算,算正方形是dp[i][j]表示以(i,j)为右下角,最大的正方形的边长,转移的时候直接根据dp[i-1][j-1]来讨论就行了。 菱形的我们把它当做是四个直角三角形,一样用dp[i][j]表示直角三角形的直角在(i,j)的最远的延伸距离。 同样dp[i][j] 根据dp[i-1][j-1]讨论。


代码:

#include <iostream>#include <vector>#include <algorithm>#include <string.h>#include <cstring>#include <time.h>#include <map>#include <set>#include <stdio.h>#include <cmath>#include <cassert>#include <math.h>#define rep(i,a,b) for(int i=(a);i<(b);++i)#define rrep(i,b,a) for(int i = (b); i >= (a); --i)#define clr(a,x) memset(a,(x),sizeof(a))#define LL long long#define eps 1e-9#define mp make_pairusing namespace std;const int maxn = 500 + 5;int n;char s[maxn][maxn];int f[maxn][maxn];int g[maxn][maxn];int l[maxn][maxn],t[maxn][maxn];int r[maxn][maxn],d[maxn][maxn];int a[maxn][maxn],b[maxn][maxn];inline int min(int a,int b) { return a < b ? a : b; }LL Sqr(){    rep(i,0,n) rep(j,0,n) f[i][j] = s[i][j];    LL ans = 0;    rep(i,1,n) rep(j,1,n) {        int k = f[i-1][j-1];        int x = min(l[i][j],t[i][j]);        if (x >= k + 1) f[i][j] = k + 1;        else f[i][j] = x;        if (f[i][j]) ans += f[i][j] - 1;    }    return ans;}LL Tri(){    rep(i,0,n) rep(j,0,n) f[i][j] = g[i][j] = a[i][j] = b[i][j] = s[i][j];    LL ans = 0;    rep(i,1,n) rep(j,1,n) {        int k = f[i-1][j-1];        int x = min(l[i][j],t[i][j]);        if (x >= k + 2) f[i][j] = k + 2;        else f[i][j] = x;    }    rep(i,1,n) rrep(j,n-2,0) {        int k = g[i-1][j+1];        int x = min(r[i][j],t[i][j]);        if (x >= k + 2) g[i][j] = k + 2;        else g[i][j] = x;    }    rrep(i,n-2,0) rep(j,1,n) {        int k = a[i+1][j-1];        int x = min(d[i][j],l[i][j]);        if (x >= k + 2) a[i][j] = k + 2;        else a[i][j] = x;    }    rrep(i,n-2,0) rrep(j,n-2,0) {        int k = b[i+1][j+1];        int x = min(d[i][j],r[i][j]);        if (x >= k + 2) b[i][j] = k + 2;        else b[i][j] = x;    }    rep(i,0,n) rep(j,0,n) {        int e1 = min(f[i][j],g[i][j]) * 2 - 1;        int e2 = min(a[i][j],b[i][j]) * 2 - 1;        e1 = min(e1,e2);        if (e1 / 2 > 0) {            char a='a';        }        ans += e1 / 2;    }    return ans;}void solve(){    clr(r,0); clr(d,0); clr(t,0); clr(l,0);    rrep(i,n-1,0) rrep(j,n-1,0) {        r[i][j] = d[i][j] = s[i][j];        if (s[i][j] == 1) {            if (i+1 < n) d[i][j] += d[i+1][j];            if (j+1 < n) r[i][j] += r[i][j+1];        }    }    rep(i,0,n) rep(j,0,n) {        l[i][j] = 0;        if (s[i][j] == 1) {            l[i][j] = 1;            if (j-1 >= 0) l[i][j] += l[i][j-1];        }        t[i][j] = 0;        if (s[i][j] == 1) {            t[i][j] = 1;            if (i - 1 >= 0) t[i][j] += t[i-1][j];        }    }    LL ans = Sqr();    ans += Tri();    printf("%lld\n",ans);}int main(){    #ifdef ACM        freopen("in.txt", "r", stdin);       // freopen("out.txt","w",stdout);    #endif // ACM    while (scanf("%d",&n)==1) {        rep(i,0,n) scanf("%s",s[i]);        rep(i,0,n) rep(j,0,n) {            if (s[i][j] == 'x') s[i][j] = 1;            else s[i][j] = 0;        }        solve();    }}


0 0
原创粉丝点击