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 ...
随机推荐
- C++中采用操作符重载完善复数类
1,复数类应该具有的操作: 1,运算:+,-,*,/: 2,比较:==,!=: 3,赋值:=: 4,求模:modulus: (5),完善的复数类操作符重载必不可少: 2,利用操作符重载: 1,统一复数 ...
- shell中#*,##*,#*,##*,% *,%% *的含义及用法
介绍下Shell中的${}.##和%%使用范例,本文给出了不同情况下得到的结果.假设定义了一个变量为:代码如下:file=/dir1/dir2/dir3/my.file.txt可以用${ }分别替换得 ...
- adb]ADB server didn't ACK
遇到上述问题 此时由于不正常退出 会在进程中遗留Android debug进程 ,需要强制删除
- c#静态变量和非静态变量的区别
静态变量的类型说明符是static.静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成 ...
- 获取模糊匹配的div id属性
html中有一批id,以数字+固定字符结尾,前台需要把这一批id组成数组传递给后台 假设固定结尾字符为“pic”,使用 var pidlist=$("[id$='pic']");将 ...
- 什么是restful风格?
文章参考 RESTful API 设计指南--阮一峰 概念 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更 ...
- setleds - 设置键盘 led 标志
总览 (SYNOPSIS) setleds [-v] [-L] [-D] [-F] [{+|-}num] [{+|-}caps] [{+|-}scroll] 描述 (DESCRIPTION) setl ...
- Codeforces 1100E 拓扑排序
题意及思路:https://blog.csdn.net/mitsuha_/article/details/86482347 如果一条边(u, v),v的拓扑序小于u, 那么(u, v)会形成环,要反向 ...
- 【转】SQLSERVER磁盘原理
[声明:本篇博客转载自http://www.cnblogs.com/ljhdo/p/5149401.html] 最近一段时间的工作主要是与SQLSERVER数据库打交道,需要对SQLSERVER有一个 ...
- oracle 中||
oracle里双竖线是字符串连接运算符!