C#|百鸡百钱窗体计算程序
1. 问题分析
1.1 题目
(1)100只鸡,100文;公鸡5文1只,母鸡3文1只,小鸡1/3文一只;求解公鸡/母鸡/小鸡各多少只?
(2)在1000只鸡,1000文,其余条件同上,求解?
(3)比较在10000只鸡,10000文条件下的循环次数和复杂度。
1.2 问题分析
1.2.1 问题组成
该问题由两个部分组成:
- 问题的解:不同条件下公鸡、母鸡和小鸡的组合
- 循环次数:用于衡量算法的时间复杂度
1.2.2 解决思路
设花了m文(m只能取100、1000或10000),买了x只公鸡、y只母鸡、z只小鸡,鸡的总数与m相同,则可得方程组:
可以使用循环的方式来寻找整数解,但是需要注意的是,并不是所有未知数都可以取到m,因此需要对这个范围进行计算以降低时间复杂度,可以得出公鸡的只数最多为\(x_{max}=m/5\),母鸡数最多为:\(y_{max}=(m-5*x-1)/3\),小鸡数为:\(z=100-x-y\)。根据此建立可建立for循环,并且循环的值i每次加一,在循环中利用if条件对符合条件的组合进行筛选,筛选条件如下:
另外,在求解复杂度和循环次数时,应当在for循环中添加一个计数器,每当循环一次,计数器加一,最后打印计数器数值。
2. WinForm界面搭建
2.1 设计Windows 窗体应用程序
2.1.1 新建项目
新建一个Windows窗体应用程序项目:
2.2.2 窗体设计
考虑到要实现的功能,主要有如下几点:
- 鸡的数量与钱的数量的输入
- 点击按钮即可出现计算结果
- 由于计算结果有很多组,需要展示
- 时间复杂度的输出
使用如下控件实现:
-
鸡的数量与钱的数量的输入使用文
-
计算结果按钮使用Button控件实现
-
计算结果使用DataGridView控件展示
-
时间复杂度使用textBox控件展示
经过调整布局后的窗体如下:
更换了窗体的图标,在Resources文件夹中可以查看并编辑图标文件:
同时为Button1绑定点击事件:
3. 添加功能
3.1 求解部分
在Button1绑定的Click事件中添加相关功能的代码,点击按钮后就可以实现求解:
在Button1绑定的Click事件中添加相关功能的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private void Main_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
int Num=0, money = 0;
try
{
Num = Convert.ToInt32(textBox1.Text);
money = Convert.ToInt32(textBox2.Text);
}
catch
{
MessageBox.Show("请输入正整数!");
}
if (Num < 0 || money < 0)
{
MessageBox.Show("请输入正整数!");
}
int Cock = 5;
int Hen = 3;
int Chicken = 1 / 3;
int forCount = 0;
List<int> Cock_num = new List<int>();
List<int> Hen_num = new List<int>();
List<int> Chicken_num = new List<int>();
for (int x = 0; x < money / Cock; x++)
{
for (int y = 0; y < (int)((money -x*5 - 1) / Hen); y++)
{
int z = Num - x - y;
forCount++;
if (z % 3 == 0 && x * Cock + y * Hen + z / 3 == money)
{
Cock_num.Add(x);
Hen_num.Add(y);
Chicken_num.Add(z);
}
}
}
string[] columnName = {"公鸡数","母鸡数","小鸡数"};//列名
DataTable dt = new DataTable();
for (int i = 0; i < columnName.Length; i++)
{
dt.Columns.Add(columnName[i], typeof(string));
}
for (int j = 0; j < Cock_num.Count; j++)
{
DataRow dr = dt.NewRow();
dr[columnName[0]] = Cock_num[j].ToString();
dr[columnName[1]] = Hen_num[j].ToString();
dr[columnName[2]] = Chicken_num[j].ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
textBox6.Text = Convert.ToString(forCount);
textBox3.Text = Convert.ToString(Cock_num.Count);
}
}
}
3.2 检查输入部分
在本次实验中,鸡的数量与钱数均需为正整数,但输入可能为小数或者负数,因此需要对输入数据进行过滤,并在用户输入错误的数据时提醒用户,避免输入小数和负数。
这里使用了try-catch和if条件语句实现该功能:
int Num=0, money = 0;
try
{
Num = Convert.ToInt32(textBox1.Text);
money = Convert.ToInt32(textBox2.Text);
}
catch
{
MessageBox.Show("请输入正整数!");
}
if (Num < 0 || money < 0)
{
MessageBox.Show("请输入正整数!");
}
效果如下:
输入小数时
输入负数时
4. 运行结果
当鸡数与钱数均为一百时:
当鸡数与钱数均为一千时:
当鸡数与钱数均为一万时: