这是前天晚上百度编程竞赛的试题,由于本人主要研究学习的是.NET技术,所以在此使用C#语言来实现需求功能: 题目:
2013年4月27日竞赛题目二
Apple
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Problem Description
小H是一个程序员,但他的生活不局限在写程序。
有一天,他走到公园散步。他见到公园的一棵苹果树上结满了苹果。他于是拿起石头,想砸几个苹果下来当第二天的早餐。突然他思考到了一个问题:怎样才能一次砸到最多苹果?
我们考虑该局面是这样一个模型:所有东西位于二维笛卡尔坐标系,其中小H位于原点,苹果们分别在坐标系的整点上。石头飞出的轨迹是一条经过原点的抛物线,确切的说,经过的是 y=ax^2+bx 的抛物线(a<0)。石头砸到一个苹果后,该苹果会落下,且石头不会改变运动轨迹。
现在小H希望求扔一个石头最多砸到的苹果数。
Input
第一行为一个整数T(1 <= T<= 10),表示有T组测试数据;
每组数据第一行一个正整数N(1<=N<=2000),表示苹果数。下面N行每行两个整数给出每个苹果的坐标xi, yi(1<=xi<=1000, 1<=yi<=1000000)。
Output
对于每组数据,输出最多可能砸到的苹果数。
Sample Input
2
4
1 3
2 4
3 3
4 4
2
1 1
1 1
Sample Output
3
2 实现代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 百度2013年4月27日竞赛题目二
{
class Program
{
static void Main(string[] args)
{
List<Array> group = new List<Array>();
int T = Convert.ToInt32(Console.ReadLine());
for (int a = 1; a <= T; a++)
{
int N = Convert.ToInt32(Console.ReadLine());
string[] pointArr = new string[N];
for (int b = 0; b < N; b++)
{
pointArr[b] = Console.ReadLine();
}
group.Add(pointArr);
}
foreach (string[] pointArr in group)
{
int Max = 0;
for (int a = 0; a < pointArr.Length; a++)
{
string[] pointXY = pointArr[a].Split(' ');
int x1 = Convert.ToInt32(pointXY[0]);
int y1 = Convert.ToInt32(pointXY[1]);
Dictionary<string, int> pointNum = new Dictionary<string, int>();
pointNum["same"] = 0;
int tempMax = 0;
for (int b = 0; b < pointArr.Length; b++)
{
pointXY = pointArr[b].Split(' ');
int x2 = Convert.ToInt32(pointXY[0]);
int y2 = Convert.ToInt32(pointXY[1]);
string pointStr = GetPointOfIntersection(x1, y1, x2, y2);
if (pointNum.ContainsKey(pointStr))
{
pointNum[pointStr]++;
}
else
{
pointNum[pointStr] = 1;
}
}
foreach (string pointStr in pointNum.Keys)
{
if (pointStr != "parallel" && pointStr != "same")
{
if (pointNum[pointStr] > tempMax)
{
tempMax = pointNum[pointStr];
}
}
}
tempMax += pointNum["same"];
if (tempMax > Max)
{
Max = tempMax;
}
}
Console.WriteLine(Max);
}
Console.ReadKey();
}
/// <summary>
/// 获取抛物线同时经过两个整点(即同时砸中两个苹果)的a和b的值
/// </summary>
/// <param name="x1">第一个整点的X坐标</param>
/// <param name="y1">第一个整点的Y坐标</param>
/// <param name="x2">第二个整点的X坐标</param>
/// <param name="y2">第二个整点的Y坐标</param>
/// <returns>a和b的值组成的字符串</returns>
public static string GetPointOfIntersection(int x1, int y1, int x2, int y2)
{
//y1*x2*x2-b*x1*x2*x2=y2*x1*x1-b*x2*x1*x1
int num1 = y1 * x2 * x2;//左边的常数
int num2 = x1 * x2 * x2;//左边的系数
int num3 = y2 * x1 * x1;//右边的常数
int num4 = x2 * x1 * x1;//右边的系数
//num1-b*num2=num3-b*num4
if (num2 == num4)
{
if (num1 != num3)
{
return "parallel";
}
else
{
return "same";
}
}
else
{
return ((num3 - num1) / (num4 - num2)).ToString();
}
}
}
}