c# 陈景润 15 子问题
初学编程时在 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 子问题的更多相关文章
- [30分钟]MSSQL快速入门教程
1.什么是SQL语句 sql语言:结构化的查询语言.(Structured Query Language),是关系数据库管理系统的标准语言. 它是一种解释语言:写一句执行一句,不需要整体编译执行.语法 ...
- [转]史上最全的MSSQL复习笔记
阅读目录 1.什么是SQL语句 2.使用sql语句创建数据库和表 3.创建数据表 4.数据完整性约束 5.四中基本字符类型说明 6.SQL基本语句 7.类型转换函数 8.日期函数 9.数学函数 10. ...
- MSSQL学习笔记
阅读目录 1.什么是SQL语句 2.使用sql语句创建数据库和表 3.创建数据表 4.数据完整性约束 5.四中基本字符类型说明 6.SQL基本语句 7.类型转换函数 8.日期函数 9.数学函数 10. ...
- 1.5.8 语言分析器(Analyzer)
语言分析器(Analyzer) 这部分包含了分词器(tokenizer)和过滤器(filter)关于字符转换和使用指定语言的相关信息.对于欧洲语言来说,tokenizer是相当直接的,Tokens被空 ...
- mysql复习笔记
阅读目录 1.什么是SQL语句2.使用sql语句创建数据库和表3.创建数据表4.数据完整性约束5.四中基本字符类型说明6.SQL基本语句7.类型转换函数8.日期函数9.数学函数10.字符串函数11.联 ...
- Javascript 常用代码总结
1. document.referrer可以获得上一页的地址,使用document.anchors获得页面上面所有的链接元素,而不必使用 document.getElementsByTagName(' ...
- 通过memcached来实现对tomcat集群中Session的共享策略
近期在做一套集群的实现,实现的方案是在Linux下完成对Apache + Tomcat 负载均衡的功能. 上述功能已经实现,有需要了解的朋友可以看我另外一篇博文. Linux下Apache与Tomca ...
- unity案例入门(二)(坦克大战)
1. 案例简述 这个案例实现一个简单的坦克对战游戏,两个玩家在一个地图上PK. 2. 控制坦克移动 与案例一中小球的移动方式不同,坦克在横向上不能是平移,因此横向按键控制的应该是坦克旋转. publi ...
- JavaScript 基础学习1-day14
JavaScript 基础学习1 知识预览JavaScript概述二 JavaScript的基础三 JavaScript的对象BOM对象DOM对象实例练习js扩展 JavaScript概述 JavaS ...
随机推荐
- 解决MVC中textarea出现多余空格的问题
public static MvcHtmlString FixedTextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> ...
- 【转】C++ STL中常见容器的时间复杂度
map, set, multimap, and multiset 上述四种容器采用红黑树实现,红黑树是平衡二叉树的一种.不同操作的时间复杂度近似为: 插入: O(logN) 查看:O(logN) 删除 ...
- java并发编程之美-阅读记录5
java并发包中的并发List 5.1CopeOnWriteArrayList 并发包中的并发List只有CopyOnWriteArrayList,该类是一个线程安全的arraylist,对其进行的修 ...
- ASP.NET Core 2.1 JWT Token 使用 (二) - 简书
原文:ASP.NET Core 2.1 JWT Token 使用 (二) - 简书 接上文,https://www.jianshu.com/p/c5f9ea3b4b65 ASP.NET Core 2. ...
- C#编程—第五天--循环语句for
for穷举法.迭代法 穷举法练习: //穷举法: //1.找100以内的与7有关的数 //2.小明单位发了一百元的购物卡,他到超市买洗化用品,一是洗发水(15元),二是香皂(2元),三是牙刷(5元)怎 ...
- C#编程--第三天
语句 语句是指程序命令,都是按照顺序执行的.语句在程序中的执行顺序称之为"控制流"或"执行流".根据程序对运行时所收到的输入的响应,在程序每次运行时程序流可能有 ...
- runtime之归档和解档
IOS开发之NSCoding协议(使用runtime)近期学习IOS的runtime库,然后看到之前写的NSCoding协议有点复杂,如果属性少还好,如果100多个属性,则会显得麻烦.下面使用常规方式 ...
- 2019-9-2-win10-uwp-切换主题
title author date CreateTime categories win10 uwp 切换主题 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 1 ...
- 转载:Spring中各个JAR包的作用
(1) spring-core.jar 这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工 ...
- Qt 显示网页的控件
Qt5.6以下的版本,基于QtWebkit控件Qt5.6以上的MSVC版本,基于 Chromium 的浏览器引擎 Qt WebEngineQt5.6以上的mingw 版本,只能采用QAxWidget ...