美登杯-小花梨的三角形(枚举)

Problem Description:

小花梨现在有一个?层三角形图(参考下图),第?层有2? − 1个边长为1的等边三角形。

每个交点处存在一个字符,总共有? + 1层字符,第?层有?个字符。

小花梨用等边三角形三个顶点上的字符来表示这个三角形,两个等边三角形如果它们的三个

顶点字符相同(不区分顺序)则视为同一类等边三角形。小花梨想知道总共存在多少种不同类

别的等边三角形。

Input:

第一行为正整数?,表示三角形层数(1 ≤ ? ≤ 100)

接下来? + 1行,第?行输入?个字符,表示第?层的字符。(字符只包含小写字母"? − ?")

Output:

输出一个整数表示存在多少种不同类别的三角形

Note:

样例一:只存在顶点为(?, ?, ?)的三角形

样例二:存在顶点为(?, ?, ?)(?, ?, ?)(?, ?, ?)3类不同的三角形

样例三:只存在顶点为(?, ?, ?)的三角形

思路:

开一个三维数组dp对已经出现过的三角形三顶点的字符组合进行标记,遍历到一个新的三顶点字符组合就看一下该组合是否已经被标记过,如果没有被标记过sum就加1。标记的时候一定要考虑到3的全排列共6种组合方式,6种组合方式都要进行标记,例如出现的是abc就要将abc、acb、bac、bca、cab、cba都进行标记。

将题目中的三角形划分为两种,一种是正三角,一种是倒三角,注意三角形并不一定是边长为1的等边三角形,还有边长为2、边长为3等的正、倒三角。

上AC代码:

#include <stdio.h>
#include <string.h>
bool dp[26][26][26];
char str[101][101];
int n;
int main()
{
    scanf("%d",&n);
    int i,j,k;
    memset(dp,0,sizeof(dp));
    for(i=0;i<n+1;i++)
    {
        scanf("%s",str[i]);
    }
    int sum=0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<i+1;j++)
        {
            //循环找正三角
            for(k=1;k<=n-i;k++)
            {
                if(dp[str[i][j]-'a'][str[i+k][j]-'a'][str[i+k][j+k]-'a']==false)
                {
                    //123
                    dp[str[i][j]-'a'][str[i+k][j]-'a'][str[i+k][j+k]-'a']=true;
                    //132
                    dp[str[i][j]-'a'][str[i+k][j+k]-'a'][str[i+k][j]-'a']=true;
                    //213
                    dp[str[i+k][j]-'a'][str[i][j]-'a'][str[i+k][j+k]-'a']=true;
                    //231
                    dp[str[i+k][j]-'a'][str[i+k][j+k]-'a'][str[i][j]-'a']=true;
                    //312
                    dp[str[i+k][j+k]-'a'][str[i][j]-'a'][str[i+k][j]-'a']=true;
                    //321
                    dp[str[i+k][j+k]-'a'][str[i+k][j]-'a'][str[i][j]-'a']=true;
                    sum++;
                }
            }
            //循环找倒三角
            for(k=1;k<=i;k++)
            {
                if(j-k>=0&&j<=i-k)
                {
                    if(dp[str[i][j]-'a'][str[i-k][j-k]-'a'][str[i-k][j]-'a']==false)
                    {
                        //123
                        dp[str[i][j]-'a'][str[i-k][j-k]-'a'][str[i-k][j]-'a']=true;
                        //132
                        dp[str[i][j]-'a'][str[i-k][j]-'a'][str[i-k][j-k]-'a']=true;
                        //213
                        dp[str[i-k][j-k]-'a'][str[i][j]-'a'][str[i-k][j]-'a']=true;
                        //231
                        dp[str[i-k][j-k]-'a'][str[i-k][j]-'a'][str[i][j]-'a']=true;
                        //312
                        dp[str[i-k][j]-'a'][str[i][j]-'a'][str[i-k][j-k]-'a']=true;
                        //321
                        dp[str[i-k][j]-'a'][str[i-k][j-k]-'a'][str[i][j]-'a']=true;
                        sum++;
                    }
                }
            }
        }
    }
    //最后一行特判
    i=n;
    for(j=0;j<n+1;j++)
    {
        //以最后一行为峰点的三角形只可能是倒三角
        for(k=1;k<=i;k++)
        {
            if(j-k>=0&&j<=i-k)
            {
                if(dp[str[i][j]-'a'][str[i-k][j-k]-'a'][str[i-k][j]-'a']==false)
                {
                    //123
                    dp[str[i][j]-'a'][str[i-k][j-k]-'a'][str[i-k][j]-'a']=true;
                    //132
                    dp[str[i][j]-'a'][str[i-k][j]-'a'][str[i-k][j-k]-'a']=true;
                    //213
                    dp[str[i-k][j-k]-'a'][str[i][j]-'a'][str[i-k][j]-'a']=true;
                    //231
                    dp[str[i-k][j-k]-'a'][str[i-k][j]-'a'][str[i][j]-'a']=true;
                    //312
                    dp[str[i-k][j]-'a'][str[i][j]-'a'][str[i-k][j-k]-'a']=true;
                    //321
                    dp[str[i-k][j]-'a'][str[i-k][j-k]-'a'][str[i][j]-'a']=true;
                    sum++;
                }
            }
        }
    }
    printf("%d\n",sum);
    return 0;
}
发布了72 篇原创文章 · 获赞 203 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/weixin_41676881/article/details/90340068