S错位形分班算法如何实现

lingyuzhishui 2009-06-14 12:36:08
基本按照S形分班,但是又要求每次循环都要错开一位,请问如何来实现将相应的名次放入各个班级?或者是将班级号插入对应的各个名次中?规律如下所示:(不考虑男女比例)

名 次
一班:1 16 24 31 39 46 54 61

二班:2 15 17 30 40 45 55 60

三班:3 14 18 29 33 44 56 59

四班:4 13 19 28 34 43 49 58

五班:5 12 20 27 35 42 50 57

六班:6 11 21 26 36 41 51 64

七班:7 10 22 25 37 48 52 63

八班:8 9 23 32 38 47 53 62
...全文
112 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
我爱程序 2011-04-11
  • 打赏
  • 举报
回复
你们写的太复杂了

--获取对应数量
Select @ManNum = IsNull(Max(OrderNo),0) From ##ManTable
Select @WomanNum = IsNull(Max(OrderNo),0) From ##WomanTable
Set @Max = Case When @ManNum > @WomanNum Then @ManNum Else @WomanNum End --获取最大的分配值
Set @CircleCount = @Max / (@ClassNum * 2) --初始循环次数
Set @Step = 1
While(@Step <= @CircleCount) --首先分配,不考虑区域限制
Begin
--计算公式:班级OrderNo + (步骤@Step - 1)*班级总数@ClassNum 从首正排序插入班级
Update #ClassTable Set ManNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##ManTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##ManTable Set CCode = a.CCode From #ClassTable a,##ManTable b Where b.OrderNo = a.OrderNo + (@Step - 1) * @ClassNum
And b.CCode = '' And a.ManNum <= @ManNum
Update #ClassTable Set WomanNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##WomanTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##WomanTable Set CCode = a.CCode From #ClassTable a,##WomanTable b,@TempArea c Where b.OrderNo = a.OrderNo + (@Step - 1) * @ClassNum
And b.CCode = '' And a.WomanNum <= @WomanNum
--计算公式:最大男生或者女生@ManNum或@WomanNum - (班级OrderNo + (步骤@Step - 1)*班级总数@ClassNum - 1) 从尾倒排序插入班级
Update #ClassTable Set ManNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##ManTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##ManTable Set CCode = a.CCode From #ClassTable a,##ManTable b Where b.OrderNo = @ManNum - (a.OrderNo + (@Step - 1) * @ClassNum - 1)
And b.CCode = '' And a.ManNum <= @ManNum
Update #ClassTable Set WomanNum = a.Num From (Select IsNull(Count(Ksh),0) As Num,CCode From ##WomanTable Group By CCode) a,#ClassTable b Where a.CCode = b.CCode
Update ##WomanTable Set CCode = a.CCode From #ClassTable a,##WomanTable b Where b.OrderNo = @WomanNum - (a.OrderNo + (@Step - 1) * @ClassNum - 1)
And b.CCode = '' And a.WomanNum <= @WomanNum
Set @Step = @Step + 1
End
lingyuzhishui 2009-06-15
  • 打赏
  • 举报
回复
太感谢cloudfang了,请问如何将结果转换为数据库中的数据,将名次列为一列,班号对应的为一列,谢谢大侠了
gawexi 2009-06-15
  • 打赏
  • 举报
回复
小王。我再来个java版的,呵呵。

先放结果吧。
list1: 1 16 24 31 39 46 54 61 69 76 84 91 99 106 114 121 129 144 152 159 167 174 182 189 197

list2: 2 15 17 30 40 45 55 60 70 75 85 90 100 105 115 128 130 143 145 158 168 173 183 188 198

list3: 3 14 18 29 33 44 56 59 71 74 86 89 101 112 116 127 131 142 146 157 161 172 184 187 199

list4: 4 13 19 28 34 43 49 58 72 73 87 96 102 111 117 126 132 141 147 156 162 171 177 186 200

list5: 5 12 20 27 35 42 50 57 65 80 88 95 103 110 118 125 133 140 148 155 163 170 178 185 193

list6: 6 11 21 26 36 41 51 64 66 79 81 94 104 109 119 124 134 139 149 154 164 169 179 192 194

list7: 7 10 22 25 37 48 52 63 67 78 82 93 97 108 120 123 135 138 150 153 165 176 180 191 195

list8: 8 9 23 32 38 47 53 62 68 77 83 92 98 107 113 122 136 137 151 160 166 175 181 190 196

不知道是不是满足你得要求。

source:

import java.util.ArrayList;

/**
* class grouping
* @author gwx
* @since 2009/06/15
* @version v1.0
*/
public class TestSclass {

/** class1 ~ class8 */
ArrayList<Integer> list1;
ArrayList<Integer> list2;
ArrayList<Integer> list3;
ArrayList<Integer> list4;
ArrayList<Integer> list5;
ArrayList<Integer> list6;
ArrayList<Integer> list7;
ArrayList<Integer> list8;

/** ranking list */
ArrayList<Integer> list;

int x = 0; // which class
int y = 0; // which column for all
/** every two columns were one group */
int z = 0; // which group

public void init(){

list1 = new ArrayList<Integer>();
list2 = new ArrayList<Integer>();
list3 = new ArrayList<Integer>();
list4 = new ArrayList<Integer>();
list5 = new ArrayList<Integer>();
list6 = new ArrayList<Integer>();
list7 = new ArrayList<Integer>();
list8 = new ArrayList<Integer>();
list = new ArrayList<Integer>();

for(int i = 1;i<=200;i++){
list.add(i);
}
}

/**
* class grouping
*/
public void replaceclass(){

for( int i : list){

x = (i-1)%8; //remainder 0 1 2 3 4 5 6 7
y = (i-1)/8; //quotient 0 1 2 3 4 5 6 7 8 9 10 11...
z = y/2; //y quotient 0 1 2 3 4 5

if(y%2 == 0){ //0 1 0 1 0 1 0 1 0 1 0 1 which column in a group

x = x+z;
setlist(i);
} else if(y%2 == 1){

x = 7-x-z;
if(x<0){

x = 8 + x%8;
}
setlist(i);
}
}
}

/**
* add ranking into class
* @param i
*/
public void setlist(int i){

if(x >= 8){

x = x%8;
}

if(x==0){

list1.add(i);
}else if(x==1){

list2.add(i);
}else if(x==2){
list3.add(i);
}else if(x==3){

list4.add(i);
}else if(x==4){

list5.add(i);
}else if(x==5){

list6.add(i);
}else if(x==6){

list7.add(i);
}else if(x==7){

list8.add(i);
}
}

/**
* out print
*/
public void out(){

System.out.print("list1:");
for(int i : list1){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list2:");
for(int i : list2){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list3:");
for(int i : list3){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list4:");
for(int i : list4){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list5:");
for(int i : list5){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list6:");
for(int i : list6){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list7:");
for(int i : list7){

System.out.print(" "+i);
}
System.out.print("\n");

System.out.print("list8:");
for(int i : list8){

System.out.print(" "+i);
}
System.out.print("\n");
}

/**
* main
* @param args
*/
public static void main(String[] args) {

TestSclass ts = new TestSclass();
ts.init();
ts.replaceclass();
ts.out();
}
}
lingyuzhishui 2009-06-15
  • 打赏
  • 举报
回复
感谢大家,感谢cloudfang,以后请大家多多指教
cloudfang 2009-06-15
  • 打赏
  • 举报
回复
错位步骤代码做个调整

/// <summary>
/// 错位
/// </summary>
/// <param name="AllGroup">完成分组步骤的分组</param>
/// <returns>完成错位步骤的分组</returns>
private ArrayList MoveGroup(ArrayList AllGroup)
{
for (int i = 0; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
int MoveIndex = Group.Count / 2;
int MoveCount = i % MoveIndex; //移动次数
for (int j = 0; j < MoveCount; j++)
{
int Move = Convert.ToInt32(Group[MoveIndex - 1]);
Group.RemoveAt(MoveIndex-1);
Group.Insert(0, Move);
Move = Convert.ToInt32(Group[Group.Count - 1]);
Group.RemoveAt(Group.Count - 1);
Group.Insert(MoveIndex, Move);
}
}
return AllGroup;
}
cloudfang 2009-06-15
  • 打赏
  • 举报
回复
步骤:分组、错位、折叠分班,为方便理解,各步分开写。
代码在VS2008下测试通过,直接复制即可运行。
详细代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

/// <summary>
/// 分组
/// </summary>
/// <param name="ClassNum">班级数</param>
/// <param name="StudentNum">学生数</param>
/// <returns>完成分组步骤的分组</returns>
private ArrayList DivideGroup(int ClassNum, int StudentNum)
{
//先把所有学生分组
ArrayList AllGroup = new ArrayList(); //存放所有分组
int GroupNum = ClassNum * 2; //每组学生数
int count = StudentNum % GroupNum == 0 ? StudentNum / GroupNum : StudentNum / GroupNum + 1; //组数
//把学生加入分组
for (int i = 1; i < count + 1; i++)
{
ArrayList Group = new ArrayList();
int StartIndex=GroupNum * (i - 1) + 1;
int EndIndex=GroupNum * i + 1;
for (int j = StartIndex; j < EndIndex; j++)
{
Group.Add(j > StudentNum ? 0 : j); //不足就用0代替
}
AllGroup.Add(Group);
}
return AllGroup;
}

/// <summary>
/// 错位
/// </summary>
/// <param name="AllGroup">完成分组步骤的分组</param>
/// <returns>完成错位步骤的分组</returns>
private ArrayList MoveGroup(ArrayList AllGroup)
{
//第一组不错位,所以从第二组开始
for (int i = 1; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
for (int j = 0; j < i; j++) //移动几次
{
int MoveIndex = Group.Count / 2;
int Move = Convert.ToInt32(Group[MoveIndex - 1]);
Group.RemoveAt(MoveIndex-1);
Group.Insert(0, Move);
Move = Convert.ToInt32(Group[Group.Count - 1]);
Group.RemoveAt(Group.Count - 1);
Group.Insert(MoveIndex, Move);
}
}
return AllGroup;
}

/// <summary>
/// 折叠分班
/// </summary>
/// <param name="AllGroup">完成错位步骤的分组</param>
/// <returns></returns>
private Hashtable DivideClass(ArrayList AllGroup)
{
Hashtable htClass=new Hashtable();
for (int i = 0; i < AllGroup.Count; i++)
{
ArrayList Group = (ArrayList)AllGroup[i];
//对于每个分组,第一个和最后一个属于一班,第二个和倒数第二个属于二班.......循环一半即可
int ClassNum=Group.Count / 2;
for (int j = 0; j < ClassNum; j++)
{
ArrayList Class = new ArrayList();
int ClassNo = (j + 1) % ClassNum == 0 ? ClassNum : (j + 1) % ClassNum;
if (htClass[ClassNo] == null)
{
Class.Add(Group[j]);
Class.Add(Group[Group.Count - 1 - j]);
htClass.Add(ClassNo, Class);
}
else
{
Class = (ArrayList)htClass[ClassNo];
Class.Add(Group[j]);
Class.Add(Group[Group.Count - 1 - j]);
}
}
}
return htClass;
}

private void button1_Click(object sender, EventArgs e)
{
Hashtable ht = DivideClass(MoveGroup(DivideGroup(8, 63)));
StringBuilder sb = new StringBuilder();
for (int i = 1; i < 9; i++)
{
ArrayList Class = (ArrayList)ht[i];
sb.Append(i.ToString() + "班:");
for (int j = 0; j < Class.Count; j++)
{
sb.Append(" " + Class[j].ToString());
}
sb.Append("\r\n");
}
this.richTextBox1.Text = sb.ToString();
}
}
}

yingzhilian2008 2009-06-14
  • 打赏
  • 举报
回复
帮顶
 OpenGL-自主高性能三维GIS平台架构与实现/第二季:实现三维GIS球体+ 高程数据章节名称DEM基础1DEM基础知识1.介绍基本的DEM知识2.什么是DEM,作用是什么2DEM数据1.如何获取/ 传统测量/激光扫描/无人机测量/ 点云数据/ 倾斜摄影2.如何使用/局部小规模(栅格数据,图片/tif),3. 组织方式4. 根据使用目的不同,介绍多种优化方法3DEM图层的实现原理14DEM数据结构定义struct  V3U3N4顶点数据的生成和计算WGS84投影计算5wgs84 投影球体被切成一个个小圆弧,一共60个投影带,分别为01,02.........60WGS的最新版本为WGS 84(也称作WGS 1984、EPSG:4326),1984年定义、最后修订于2004年。接口定义坐标转换Wgs84 数据加载6瓦片编号计算生成算法1. 经纬度到大地坐标的转换2.大地坐标到经纬度坐标转换3. 根据经纬度获取瓦片编号框架重构7智能指针重构框架1. 基类定义(所有的类继承自基类),基类派生自 std::enbale_shared_from_this2. 实现智能指针的动态转换接口3. 实现向下转换4. 已有的类实现全部使用智能指针重构5. 任务系统(多线程加载任务)8引入图层(Layer)1. 介绍图层的概念以及重要性2. 图层类实现3. 修改框架(使用图层的方式重构框架)9Layer-bug排查(绘制过程中出现错位,偶发)1. 框架重构后遇到问题(绘制结果错误)2. 瓦片索引方式发生变化,多线程中引起内存问题3. 修改索引方式,解决绘制偶发错误问题10引入数据源(TileSource)1. 数据源的作用与设计目的2. 当前存在的问题,数据调度中存在问题3. 数据源(TileSource)类实现11数据格式管理(FormatMgr)1. 数据格式管理(FormatMgr) 提出的目的,需要解决的问题2. CELLFormat基类接口抽象3. 实现几个标准格式类4. 修改框架流程,使用FormatMgr重构流程5. 扩展支持,后续支持任务格式数据加入系统12Task(任务)优化1. 任务中低耦合数据结构,目的是让Task更加的通用2. 修改任务读取代码与任务处理代码,完善处理流程DEM高程13DEM-数字高程定义1. 什么是数字化高程数据2. 当下GIS系统中有哪些常见的高程格式3. 课程体体系中使用的哪种格式4. 高程类定义以及实现,并加入到FormatMgr 管理系统中14高程瓦片数据读取1. 介绍GIS系统相关的工具(在数据转换)数据生成方面可以解决大量时间2. 自定义高程瓦片格式说明3. 自定义高程格式文件解析,并以智能对象的方式引入到系统中4. 完善框架代码,适配高程数据15高程瓦片文件的读取1. 实现基本的读取算法2. 增加格式化组件,并加入到系统中3. 配置高程图层以及高程数据源,并加载数据,验证数据正确性16瓦片数据结构重构1.顶点生成2.UV坐标计算3.面数据生成17DEM重构绘制流程1. 修改绘制数据结构,去除无用字段2. 增加Mesh类,实现光栅数据转换成三角面数据,计算UV数据,提炼接口3. 修改系统调度,实现顶点数据,UV数据,以及面数据的生成与更新4. 按需更新数据,而不是每一帧更新18DEM-数据精度问题(CPU)1. 因为瓦片数据使用大地坐标作为系统输入,造成瓦片坐标很大,单浮点数据精度不够2. 使用局部坐标的方式解决单浮点精度问题3. 调整相机参数,解决投影矩阵数据计算深度精度问题4. 修改绘制shader 实现对瓦片数据的绘制19DEM-数据精度问题(LogDepth)1. 使用对数深度(log depth )算法在GPU中 计算解决单浮点经纬计算问题2. 修改shader ,增加对(logDepth)算法支持3. 修改C++端代码,实现对shader数据的输入20DEM-数据结构优化1.当下使用CPU端数据通过接口的方式传递给GPU,速度慢2. 使用Instance 方式降低Vertex Buffer 的大小,优化渲染系统21DEM-GPU缓冲区优化1. 使用Vertex Buffer Object / Index Buffer Object  / Instance  方式优化渲染系统2. 修改绘制接口,使用DrawElementsInstanceBaseInstance方式提升系统性能内存池与对象池22瓦片生成优化/对象池1. 相机移动过程中会频繁的建立与释放瓦片,对CPU有较大的消耗2. 引入内存池,避免频繁的内存申请与释放,降低CPU时间3. 改造智能指针对象,对象释放通知到内存管理,回收对象内存23改造任务系统支持对象池1. 任务系统是一个公用模块,被多个模块使用,避免频繁的内存操作,引起的内存碎片2. 实现对象池,并应用到任务模块法线计算24法线计算1. 修改现有顶点结构,增加法线支持2. 修改shader,增加法线顶点输入,使用平行光光照模型3. 修改绘制流程,支持光照计算,使用探照灯作为光源输入25顶点法线计算/共享法线计算1. 增加数据结构保存顶点数据被多个面共享的次数2. 计算面法线,并累加到顶点法线中3. 根据顶点被面共享的次数做平均法线计算4. 修改流程,按需更新法线数据26法线数据压缩1. 法线数据使用3 * float 数据存储,大大的增加了系统的数据2. 实现算法,将3 * float 数据压缩成4字节数据3. 改造绘制代码,支持压缩数据输入27GPU中计算产生法线数据(去掉CPU中计算)1. 引擎支持 Geometry Shader 阶段2. 编写 Geometry Shader,实现法线计算系统功能优化28重构CPU拾取流程1. 当下的拾取流程,只支撑二维数据拾取,无法准群的拾取三维数据2. Terrain中增加拾取接口,输入射线,输出拾取到顶点数据29绘制拾取结果1. 增加一个绘制点的方法,实现绘制代码2. 修改shader,增加logdepth3. 调试代码,花费了很多时间排查错误,最总排查到是因为uniform参数笔误写错造成。30任务系统完善,避免任务队列无线膨胀1. 任务系统中,没有限制队列的大小,生产者的能力远大于消费者的能力,造成任务队列膨胀2. 处理办法,限制生产者的生产能力,而不是限制任务队列大小(这种方式会造成业务逻辑异常复杂)3. 使用sleep休眠方式(这种方式是严重错误的)31如何避免瓦片数据抖动1. 产生瓦片抖动的原因 ? 分裂算法与回退算法中间没有过度2. 引入过度流程,避免内存抖动,参数因子是一个重要的数据,需要谨慎使用3. 有必要结合瓦片自身数据动态计算参数因子32瓦片数据管理-fepk文件格式支持-全球数据加载1. 支持fepk文件格式,增加fepk读取组件,适配fepk文件2. fepk管理数据方式:一般情况选择全球前10级别作为基础级别,因数据量不大(1G)左右,后续以8级作为基础级别,全球19级别数据被划分为 2^8 * 2^7(512 * 256)个块。每个块中包含了256 * 256 张小瓦片33fepk高程数据读取 34高程分裂处理当瓦片没有高程数据,那么子节点以及其他后代节点该如何共享父节点的数据35lesson-734-高程瓦片分裂处理(2)-算法实现高程数据分裂算法实现实现对高程数据的切分,并对特殊数据进行处理36高程瓦片分裂处理(3)-问题排查 37高程瓦片分裂处理(4)-(后代节点更新问题)当一个瓦片高程数据更新后,他的儿子节点,孙子节点...该如何处理?38瓦片视锥裁剪错误高程数据更新后,没有技术计算瓦片包围盒信息,造成包围盒错误,进而引视锥计算错误39http支持1.引入三方库 Libcurl2.http类封装,支持http读取数据40fepk.server使用 生成三维地球41改造四叉树-统一使用经纬度输入42地网络生成算法重构 43引入球体坐标系 44使用球体坐标改造瓦片 45多图层(加载标签数据) 课时截图:镜头拉近后,显示细节数据加载矢量SHP国界线数据:加载矢量三维白膜数据截图高程数据加载点云数据 加载倾斜摄影数据 

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧