UVA 10593 - Kites(DP)

来源:互联网 发布:2016网络诈骗案破案率 编辑:程序博客网 时间:2024/04/28 00:42

UVA 10593 - Kites

题目链接

题意:给定一张纸,问能剪出如题目所述的风筝有几种方法
思路:正方形和菱形分开考虑,不过dp[i][j]都表示以(i,j)为右下角,所构成图形的边长,那么状态转移为往之前两个方向的最小边长。但是有一些特殊情况要判断,这个在纸上画一画就很清楚了
代码:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 505;int n, dp1[N][N], dp2[N][N];char g[N][N];int main() {    while (~scanf("%d", &n)) {    memset(dp1, 0, sizeof(dp1));    memset(dp2, 0, sizeof(dp2));    for (int i = 1; i <= n; i++)        scanf("%s", g[i] + 1);    int tmp, ans = 0;    for (int i = 1; i <= n; i++) {        for (int j = 1; j <= n; j++) {        if (g[i][j] == 'x') {            tmp = min(dp1[i][j - 1], dp1[i - 1][j]);            dp1[i][j] = tmp + (g[i - tmp][j - tmp] == 'x');            tmp = min(dp2[i - 1][j - 1], dp2[i - 1][j + 1]);            if (tmp == 0 || g[i - 1][j] != 'x')            dp2[i][j] = 1;            else {            if (g[i - 2 * tmp][j] == 'x' && g[i - 2 * tmp + 1][j] == 'x') {                dp2[i][j] = tmp + 1;            }            else                dp2[i][j] = tmp;            }            ans += dp1[i][j] - 1 + dp2[i][j] - 1;        }        }    }    printf("%d\n", ans);    }    return 0;}
1 0
原创粉丝点击