有如下5*4的图形请分别输出一共有多少个下面的图形
1、正方形
2、矩形(不含正方形)
3、三角形
4、平行四边形(不含矩形和正方形)然后推广到m*n(n<=m)的图形。
1、正方形
2、矩形(不含正方形)
3、三角形
4、平行四边形(不含矩形和正方形)然后推广到m*n(n<=m)的图形。
解决方案 »
- DataGridView显示的行数怎么少了?
- 定位新弹出的窗体的位置(新窗体正好覆盖掉combox下拉的那个位置)
- 一个action和invoke的问题
- 求教数据库连接字符串的问题
- 求算法:学生数不定,老师10名,每个老师分到的学生数可以不同,每个老师所带学生的平均分数相差越小越好
- 执行Response.Write(....)会弹出空白窗体
- 怎样用WindowsMediaPlayer控件播放音频文件的任何一部分?
- 如何用stream通过Internet传送数据?
- C#中的timer控件的响应事件为什么有是tick有的是elapsed?
- 简单的问题,但是我没有例子,也找不到方法,急切!:主窗体怎样调用另外的窗体,需要窗体引用的语句是怎样的
- 分层添加数据的一个疑问。
- 嵌入的语句不能是声明或标记语句
不知大家有没有注意,m*n(n<=m)这个条件,m与n可一大一小,也可相等,其实就是任意矩形!
static void Main()
{
int m = 5, n = 4; PointF[] points = new PointF[(m + 1) * (n + 1) + m * n];
// 添加方格的交点
for (int i = 0; i < m + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
points[i * (n + 1) + j] = new PointF(i, j);
}
}
int count = (m + 1) * (n + 1);
// 添加斜线的交点
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
points[count + i * n + j] = new PointF(i + 0.5f, j + 0.5f);
}
}
count += m * n; int rectangleCount = 0, squareCount = 0, triangleCount = 0, parallelogramCount = 0; for (int a = 0; a < count; a++)
{
for (int b = a + 1; b < count; b++)
{
for (int c = b + 1; c < count; c++)
{
int? ab = GetAngle(points[a], points[b]);
int? ac = GetAngle(points[a], points[c]);
int? bc = GetAngle(points[b], points[c]); if (ab.HasValue && ac.HasValue && bc.HasValue && !(ab == ac && ac == bc))
{
triangleCount++;
//Console.WriteLine("三角形> {0}, {1}, {2}", points[a], points[b], points[c]);
}
for (int d = c + 1; d < count; d++)
{
int? ad = GetAngle(points[a], points[d]);
int? bd = GetAngle(points[b], points[d]);
int? cd = GetAngle(points[c], points[d]); int side1, side2;
int? diagonal1, diagonal2; // c 在 a 的对位的情况
/*
a ----- b
/ /
/ /
d ----- c
*/
if (ab.HasValue && bc.HasValue && cd.HasValue && ad.HasValue && ab == cd && ad == bc && ab != ad)
{
side1 = ab.Value;
side2 = ad.Value;
diagonal1 = ac;
diagonal2 = bd;
}
// b 在 a 的对位的情况
else if (ac.HasValue && bc.HasValue && bd.HasValue && ad.HasValue && ac == bd && bc == ad && ac != bc)
{
side1 = ac.Value;
side2 = bc.Value;
diagonal1 = ab;
diagonal2 = cd;
}
// d 在 a 的对位的情况
else if (ab.HasValue && bd.HasValue && cd.HasValue && ac.HasValue && ab == cd && ac == bd && ab != ac)
{
side1 = ab.Value;
side2 = ac.Value;
diagonal1 = ad;
diagonal2 = bc;
}
else
{
continue;
} // 判断两边的夹角是否为 90 度
if (Math.Abs(side1) + Math.Abs(side2) == 90)
{
// 判断对角线的夹角是否为 90 度
if (diagonal1.HasValue || diagonal2.HasValue)
{
squareCount++;
}
else
{
rectangleCount++;
//Console.WriteLine("矩形> {0}, {1}, {2}, {3}", points[a], points[b], points[c], points[d]);
}
}
else
{
parallelogramCount++;
//Console.WriteLine("平行四边形> {0}, {1}, {2}, {3}", points[a], points[b], points[c], points[d]);
}
}
}
}
} Console.WriteLine("运算 {0} x {1} 的结果如下: ", m, n);
Console.WriteLine("1、正方形: {0}", squareCount);
Console.WriteLine("2、不含正方形的矩形: {0}", rectangleCount);
Console.WriteLine("3、三角形: {0}", triangleCount);
Console.WriteLine("4、不含矩形的平行四边形: {0}", parallelogramCount); Console.ReadKey();
}/// <summary>
/// 只返回 -45度、 0 度、 45 度或 90 度,其余返回 null,因为按题目能组成图形的只有这几种角度。
/// </summary>
static int? GetAngle(PointF p1, PointF p2)
{
float width = p1.X - p2.X;
float height = p1.Y - p2.Y; if (width == 0)
{
if (p1.X % 1 != 0.5) return 90;
}
else if (height == 0)
{
if (p1.Y % 1 != 0.5) return 0;
}
else if (width == height)
{
return 45;
}
else if (width == -height)
{
return -45;
} return null;
}
运算 1 x 1 的结果如下:
1、正方形: 1
2、不含正方形的矩形: 0
3、三角形: 8
4、不含矩形的平行四边形: 0运算 2 x 1 的结果如下:
1、正方形: 3
2、不含正方形的矩形: 1
3、三角形: 18
4、不含矩形的平行四边形: 2运算 2 x 2 的结果如下:
1、正方形: 10
2、不含正方形的矩形: 8
3、三角形: 44
4、不含矩形的平行四边形: 85运算 5 x 4 的结果如下:
1、正方形: 92
2、不含正方形的矩形: 308
3、三角形: 360
4、不含矩形的平行四边形: 220
1 找出所有点Point(x,y)
2 用点组合出所有的正方形Square(pointA,pointB,pointC,pointD)
3 去掉重复的正方形
这题用公式法求解是最容易想到的,但应该也是最难做到通用,而且也是最难的解法。不信你试着总结其中一个公式试试。还有两种解法:
1. 计算点的组合。这里的“点”应该包括横竖线交点的组合,同时也包括斜线交点的组合。用点与点之间的连线(6条)和这些连线之间的夹角来判断是否能够组成我们所需要的图形。
2. 计算线的组合。这里的“线”包括横竖线和斜线,而且这个线必须是“线段”,先计算多条线是否能组成环,再计算夹角。
我觉得 1 比较容易实现,参考39楼的代码。---
39楼的代码如果要做到任何图形通用,只需要把GetAngle做成求真正的弧度: arc sin。