初学编程时在 csdn 上写过一个陈景润 15 子问题的项目,https://blog.csdn.net/weixin_41628344/article/details/79171846

当时的主要精力都放在学习编程上,并未对陈景润的算法进行研究,今天故地重游,重新整理一下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace FifteenButtons
{
class Program
{
static void Main(string[] args)
{
(new FrmMain()).ShowDialog();
}
}
public class ChessMan : Button
{
public int RowIndex { get; set; }
public int ColumnIndex { get; set; }
public int Index { get; set; }
} class FrmMain : Form
{
private List<ChessMan> chessManList;
private int N = ; //边长
private int X0 = ; //横向起始坐标
private int Y0 = ; //竖向起始坐标
private int Step = ; //按钮间距
private int CmWidth = ; //按钮宽度
private int MoveCount = ; //移动次数
private ChessMan hiddenCm;
public FrmMain()
{
Start();
}
#region Event
//开始
private void Start()
{
if (chessManList == null)
{
InitChessMan();
}
//MoveCm();
MoveCm2();
} //点击按钮
private void ChessMan_Click(object sender, EventArgs e)
{
ChessMan cm = sender as ChessMan;
int differ = Math.Abs(cm.Index - hiddenCm.Index);
if (differ == || differ == N)
{
ExChange(ref hiddenCm, cm);
}
if (GameOver())
{
MessageBox.Show("游戏结束");
Start();
}
}
#endregion #region Method
//初始化所有按钮
private void InitChessMan()
{
chessManList = new List<ChessMan>();
for (int i = ; i < N * N; i++)
{
ChessMan cm = new ChessMan();
cm.Text = (i + ).ToString();
cm.RowIndex = i / N;
cm.ColumnIndex = i % N;
cm.Index = i;
cm.Width = CmWidth;
cm.Height = CmWidth;
cm.Top = Y0 + cm.RowIndex * Step;
cm.Left = X0 + cm.ColumnIndex * Step;
if (i == (N * N - ))
{
cm.Visible = false;
this.hiddenCm = cm;
}
else
{
cm.Visible = true;
}
chessManList.Add(cm);
cm.Click += new EventHandler(ChessMan_Click);
this.Controls.Add(cm);
}
} //打乱所有按钮
private void MoveCm()
{
Random rnd = new Random();
for (int i = ; i < MoveCount; i++)
{
int direction = rnd.Next();
switch (direction)
{
//上
case :
{
if (this.hiddenCm.RowIndex == )
{
break;
}
int index = this.hiddenCm.ColumnIndex + N * (this.hiddenCm.RowIndex - );
ChessMan cm = chessManList[index];
ExChange(ref this.hiddenCm, cm);
break;
}
//下
case :
{
if (this.hiddenCm.RowIndex == (N - ))
{
break;
}
int index = this.hiddenCm.ColumnIndex + N * (this.hiddenCm.RowIndex + );
ChessMan cm = chessManList[index];
ExChange(ref this.hiddenCm, cm);
break;
}
//左
case :
{
if (this.hiddenCm.ColumnIndex == )
{
break;
}
int index = this.hiddenCm.ColumnIndex - + N * (this.hiddenCm.RowIndex);
ChessMan cm = chessManList[index];
ExChange(ref this.hiddenCm, cm);
break;
}
//右
case :
{
if (this.hiddenCm.ColumnIndex == (N - ))
{
break;
}
int index = this.hiddenCm.ColumnIndex + + N * (this.hiddenCm.RowIndex);
ChessMan cm = chessManList[index];
ExChange(ref this.hiddenCm, cm);
break;
}
}
}
} //打乱所有按钮
//陈景润方法
//http://www.doc88.com/p-7092015263762.html
private void MoveCm2()
{
Random rnd = new Random();
List<int> list = new List<int>();
for (int i = ; i < N * N; i++)
{
list.Add(i);
}
List<int> list2 = new List<int>();
while (list.Count > )
{
int i = list[rnd.Next(list.Count)];
list.Remove(i);
list2.Add(i);
} //计算倒置数
int count = ;
for (int i = ; i < list2.Count; i++)
{
if (list2[i] != list2.Count - )
{
for (int j = i + ; j < list2.Count; j++)
{
if (list2[i] > list2[j])
{
count++;
}
}
}
}
//空白所在行号
int rowIndex = ;
for (int i = ; i < list2.Count; i++)
{
if (list2[i] == N * N - )
{
rowIndex = i / N;
break;
}
}
bool list2IsOdd = (count % == ) ? false : true;
bool rowIsOdd = (rowIndex % == ) ? true : false; //0行为奇数,1行为偶数
if (N % == ) //N为偶数:序列为偶置序列,空格必须在偶数行。序列为奇置序列,空格必须在奇数行。
{
if (!list2IsOdd && rowIsOdd) //偶置序列 空格行号为奇数
{
int temp = list2[list2.Count - ]; //交换后两个元素,改变奇偶性
list2[list2.Count - ] = list2[list2.Count - ];
list2[list2.Count - ] = temp;
}
else if (list2IsOdd && !rowIsOdd)//奇置序列 空格行号为偶数
{
int temp = list2[]; //交换前两个元素,改变奇偶性
list2[] = list2[];
list2[] = temp;
}
}
else //N为奇数,序列必须为偶置序列
{
if (list2IsOdd)
{
if (rowIsOdd)
{
int temp = list2[N]; //交换后两个元素,改变奇偶性
list2[N] = list2[N + ];
list2[N + ] = temp;
}
else
{
int temp = list2[]; //交换前两个元素,改变奇偶性
list2[] = list2[];
list2[] = temp;
}
}
} for (int i = ; i < chessManList.Count; i++)
{
chessManList[i].Text = (list2[i] + ).ToString();
if (list2[i] == chessManList.Count - )
{
chessManList[i].Visible = false;
hiddenCm = chessManList[i];
}
else
{
chessManList[i].Visible = true;
}
}
}
//交换按钮
private void ExChange(ref ChessMan hiddenCm, ChessMan cm)
{
string str = hiddenCm.Text;
hiddenCm.Text = cm.Text;
cm.Text = str; hiddenCm.Visible = true;
cm.Visible = false;
hiddenCm = cm;
this.hiddenCm = hiddenCm;
} //游戏结束
private bool GameOver()
{
for (int i = ; i < chessManList.Count; i++)
{
if (chessManList[i].Text != (i + ).ToString())
{
return false;
}
}
return true;
}
#endregion
}
}

c# 陈景润 15 子问题的更多相关文章

  1. [30分钟]MSSQL快速入门教程

    1.什么是SQL语句 sql语言:结构化的查询语言.(Structured Query Language),是关系数据库管理系统的标准语言. 它是一种解释语言:写一句执行一句,不需要整体编译执行.语法 ...

  2. [转]史上最全的MSSQL复习笔记

    阅读目录 1.什么是SQL语句 2.使用sql语句创建数据库和表 3.创建数据表 4.数据完整性约束 5.四中基本字符类型说明 6.SQL基本语句 7.类型转换函数 8.日期函数 9.数学函数 10. ...

  3. MSSQL学习笔记

    阅读目录 1.什么是SQL语句 2.使用sql语句创建数据库和表 3.创建数据表 4.数据完整性约束 5.四中基本字符类型说明 6.SQL基本语句 7.类型转换函数 8.日期函数 9.数学函数 10. ...

  4. 1.5.8 语言分析器(Analyzer)

    语言分析器(Analyzer) 这部分包含了分词器(tokenizer)和过滤器(filter)关于字符转换和使用指定语言的相关信息.对于欧洲语言来说,tokenizer是相当直接的,Tokens被空 ...

  5. mysql复习笔记

    阅读目录 1.什么是SQL语句2.使用sql语句创建数据库和表3.创建数据表4.数据完整性约束5.四中基本字符类型说明6.SQL基本语句7.类型转换函数8.日期函数9.数学函数10.字符串函数11.联 ...

  6. Javascript 常用代码总结

    1. document.referrer可以获得上一页的地址,使用document.anchors获得页面上面所有的链接元素,而不必使用 document.getElementsByTagName(' ...

  7. 通过memcached来实现对tomcat集群中Session的共享策略

    近期在做一套集群的实现,实现的方案是在Linux下完成对Apache + Tomcat 负载均衡的功能. 上述功能已经实现,有需要了解的朋友可以看我另外一篇博文. Linux下Apache与Tomca ...

  8. unity案例入门(二)(坦克大战)

    1. 案例简述 这个案例实现一个简单的坦克对战游戏,两个玩家在一个地图上PK. 2. 控制坦克移动 与案例一中小球的移动方式不同,坦克在横向上不能是平移,因此横向按键控制的应该是坦克旋转. publi ...

  9. JavaScript 基础学习1-day14

    JavaScript 基础学习1 知识预览JavaScript概述二 JavaScript的基础三 JavaScript的对象BOM对象DOM对象实例练习js扩展 JavaScript概述 JavaS ...

随机推荐

  1. docker--container的port映射

    使用nginx为例 先运行nginx [root@localhost ~]# docker run --name web -d nginx Unable to find image 'nginx:la ...

  2. 致命错误: Call to undefined function %y-%M-%d()

    在TP5.0中套模板时出现的问题: 原有html模板代码: <input type="text" onfocus="WdatePicker({ maxDate:'# ...

  3. 初始 vue

    1.js,jQuery编程范式:命令式编程 vue编程范式:声明式编程 v-for   遍历数组内容 v-on: click   监听点击事件,语法糖 @click el: 类型:string | H ...

  4. redis系统管理命令

    exists 和 del exists key:判断一个key是否存在,存在返回1,否则返回0. del key:删除某个key,或是一系列key type 和 keys type key:返回某个k ...

  5. 转载:tomcat过程原理

    基于Java的Web 应用程序是 servlet.JSP 页面.静态页面.类和其他资源的集合,它们可以用标准方式打包,并运行在来自多个供应商的多个容器.Web 应用程序存在于结构化层次结构的目录中,该 ...

  6. pod的状态分析

    Pod状态 状态 描述 Running 该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建.至少有一个容器正在运行,或者正处于启动或重启状态. Pending Pod 已被 Kuber ...

  7. 10.ThreadLocal

    /** * - void set(Object value)设置当前线程的线程局部变量的值. * - public Object get()该方法返回当前线程所对应的线程局部变量. * - publi ...

  8. disk或者Partition镜像的制作

    备份镜像还原一般都是在client-server端这边才有涉及,不过作为平时爱折腾的咸鱼,表示偶尔玩玩这种操作也不错: 工具:pc  X  1(装有 大白菜,装机吧,一类制作pe软件的即可,大同小异) ...

  9. mysql添加中文数据失败

    日志信息: INFO 2015-01-13 10:44:36,078 org.springframework.beans.factory.xml.XmlBeanDefinitionReader: Lo ...

  10. JavaSE---用户交互---获取键盘输入

    1.概述 1.1 JDK1.5提供了Scanner类,用来获取键盘输入: 1.2 Scanner类是   一个基于正则表达式的文本扫描器,可以从文件.输入流.字符串中解析出基本类型值.字符串值: 1. ...