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;
}