[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

【练习-059】批处理解实现自动新生分班

出题目的:
    让大家熟练掌握随机数概念和用法
解题要求:
    1、代码简洁、高效、通用并不生成临时文件
    2、请版主级会员暂缓解题,但可跟贴为新人做指导
加分规则:
    本题满分15分,视情况加分
题目如下:
    某学校要新招收400名学生,其中有100名优等生、100名高等生、100名中等生、100名差等生,现在学校校长要求将这400名
学生随机安排到新开的10个班,同时要求每个班有10名优等生、10名高等生、10名中等生、10名差等生,并且要在学生报到的时候
就分好班次,并且他要为两个学生开后门,一个是将教育局局长的儿子分到第3班,一个是将文化局局长的女儿分到第8班。这下可
难坏了招生办的老师,一时都不知道怎么办,正好这时教务处长来了,他马上想到一个好办法,终于招生办解决了校长交给的难题,
受到校长的表扬。现在假设你是教务处长,你能想到什么好办法吗?请注意,我不是要你们写文字,要看你们的代码,请最后将每个
班的学生显示出来(最好是分屏显示)
随题提示:
    1、优等生用A-1至A-100表示,高等生用B-1至B-100表示,中等生用C-1至C-100表示,差等生用D-1至D-100表示
    2、教育局局长的儿子用B-60表示,文化局局长的女儿用C-49表示
    3、班级用X-1至X-10表示
    4、假设学生报到的顺序不是随机的,是按A-D、1-100的顺序来进行,即先按1-00的顺序招收优等生,再按1-100的顺序招收高等
生,依此类推直到招收D-100,所以才要求在报到时就随机分好班

要睡觉了,看来本题确实有难度,先给出本人的参考答案吧,不过大家还是争取不要看答案哦:


  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (A B C D) do (
  3.     for /l %%b in (1,1,100) do set ".!random!_%%a-%%b=%%a-%%b"
  4.     for /f "tokens=2 delims==" %%b in ('set .') do (
  5.         if not defined code set "code=123456789a"&set /a n=10
  6.         set /a a=!random!%%n
  7.         for %%c in (!a!) do (
  8.             set "a=!code:~%%c,1!"
  9.             for %%c in (!a!) do (
  10.                 set "code=!code:%%c=!"&set "X-%%c=!X-%%c! %%b"&set /a n-=1
  11.                 for %%d in (B-3 C-8) do (
  12.                     for /f "tokens=1,2 delims=-" %%e in ("%%d") do (
  13.                         if %%e equ %%a if %%f equ %%c if not defined _%%e%%f set "_%%e%%f=%%b"
  14.                     )
  15.                 )
  16.                 for %%d in (B-60 C-49) do if "%%d" equ "%%b" set ".%%d=X-%%c"
  17.             )  
  18.         )
  19.     )
  20.     for /f "delims==" %%b in ('set .') do set "%%b="
  21. )
  22. set "X-10=%X-a%"
  23. if "%X-3:B-60=%" equ "%X-3%" set "X-3=!X-3:%_B3%=B-60!"&call,set "!.B-60!=%%!.B-60:B-60=%_B3%!%%"
  24. if "%X-8:C-49=%" equ "%X-8%" set "X-8=!X-8:%_C8%=C-49!"&call,set "!.C-49!=%%!.C-49:C-40=%_C8%!%%"
  25. for /l %%a in (1,1,10) do cls&echo X-%%a班:&echo.&echo !X-%%a:~1!&pause>nul
复制代码

-------------------------------------------------------------------------------------------------------------------------------------------
此代码重复随机,不可取,请大家看后面的代码。

[ 本帖最后由 batman 于 2010-6-29 09:22 编辑 ]
***共同提高***

每个班规定40人吗
那两个开后门的是差等生,还是?
那个所谓的办法,能用文字表达一下吗?
技术问题请到论坛发帖求助!

TOP

回复 2楼 的帖子

1、是的,因为题目里面说“同时要求每个班有10名优等生、10名高等生、10名中等生、10名差等生”。
2、B代表高等、C代表中等。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复 2楼 的帖子

所谓的办法在每个人的心中,呵呵。。。

如觉得有难度,先可不开后门(本来就反对开后门

[ 本帖最后由 batman 于 2010-6-27 20:44 编辑 ]
***共同提高***

TOP

应该不难,但要求简洁。。。只怕有难度。
技术问题请到论坛发帖求助!

TOP

  1. @echo off & setlocal enableDelayedExpansion
  2. for %%c in (A B C D) do (
  3.   set "Max=10"
  4.   for /l %%i in (0 1 9) do (set "ptClass%%i=%%i"& set Cnt%%i=0)
  5.   for /l %%s in (1 1 100) do (
  6.     set /a to_pt=!random! %% !Max!
  7.     set /a "to=ptClass!to_pt!"
  8.     for %%t in (!to!) do (
  9.       set "X-%%t=!X-%%t! %%c-%%s"
  10.       set /a Cnt%%t+=1
  11.       if !Cnt%%t! geq 10 (
  12.         set /a last=Max-1
  13.         set /a tt=ptClass!to_pt!
  14.         set /a ptClass!to_pt!=ptClass!last!
  15.         set /a ptClass!last!=tt
  16.         set /a Max-=1
  17.       )
  18.     )
  19.   )
  20. )
  21. set "X-10=!X-0!"& set "X-0="
  22. for /l %%i in (1 1 10) do set "X-%%i=!X-%%i! "& rem 加入尾部空格防止单数错误替换
  23. echo 开后门之前...
  24. set X-
  25. pause
  26. echo 开后门...
  27. call :backDoor B-60 X-3 11
  28. call :backDoor C-49 X-8 21
  29. echo 开后门之后...
  30. set X-
  31. pause
  32. exit /b
  33. :backDoor 学生编号 班编号 班内目标号 C-49 安排到 X-8, C 起始于 #21
  34. for /l %%i in (1 1 10) do (
  35.   if /i "X-%%i" neq "%2" (
  36.     (echo !X-%%i!|find /i "%1">nul)&&(
  37.       for /f "tokens=%3 delims= " %%t in ("!%2!") do (
  38.         (echo 调换: X-%%i 班的 %1 ^<==^> %2 班的 %%t )
  39.         set "X-%%i=!X-%%i:%1 =%%t !" & rem 带尾部空格防止双数被当成单数替换,
  40.         set "%2=!%2:%%t =%1 !"       & rem 例: B-12 会当作 B-1 与 2
  41.       )  
  42.       exit /b
  43.     )
  44.   )
  45. )
  46. exit /b
复制代码

[ 本帖最后由 neorobin 于 2010-6-27 21:38 编辑 ]
1

评分人数

    • batman: 思路再打开点,代码确实难以很简洁PB + 10

TOP

开后门还真是有难度,思考中。。。。。
技术问题请到论坛发帖求助!

TOP

回复 7楼 的帖子

我的方法是先全部 平等 对待 安排, 之后再找出相应的 班和学生 调换一下(如果已经安排到了所要的班就免调换了)即可,  前部的代码排除了 特殊性, 可以写得简洁

TOP

开后门也不难,思路打开点,试试交换法,嘿嘿。。。
***共同提高***

TOP

回复 9楼 的帖子

对, 不需要调换学生, 找到所在的班, 直接和想要的班换一下就可以了, 实质上也就是把后门学生所要的班号 换成 所要求的就行了, 比如 B-60 被安排到了 8 班, 那么直接把 8 班看成 3  班, 3 班看成 8 班就行了!

TOP

开窍了,哈哈,是的,任何问题从多个角度上来想,总能找到解决的好办法的。
***共同提高***

TOP

再发换班不换学生的

这里换班号的方法是错误的, 13楼, 14楼 有说明
  1. @echo off & setlocal enableDelayedExpansion
  2. for %%c in (A B C D) do (
  3.   set "Max=10"
  4.   for /l %%i in (0 1 9) do (set "ptClass%%i=%%i"& set Cnt%%i=0)
  5.   for /l %%s in (1 1 100) do (
  6.     set /a to_pt=!random! %% !Max!
  7.     set /a "to=ptClass!to_pt!"
  8.     for %%t in (!to!) do (
  9.       set "X-%%t=!X-%%t! %%c-%%s"
  10.       set /a Cnt%%t+=1
  11.       if !Cnt%%t! geq 10 (
  12.         set /a last=Max-1
  13.         set /a tt=ptClass!to_pt!
  14.         set /a ptClass!to_pt!=ptClass!last!
  15.         set /a ptClass!last!=tt
  16.         set /a Max-=1
  17.       )
  18.     )
  19.   )
  20. )
  21. set "X-10=!X-0!"& set "X-0="
  22. for /l %%i in (1 1 10) do set "X-%%i=!X-%%i! "& rem 加入尾部空格防止单数错误替换
  23. echo 开后门之前...
  24. set X-
  25. pause
  26. echo 开后门...
  27. call :backDoor B-60 X-3
  28. call :backDoor C-49 X-8
  29. echo 开后门之后...
  30. set X-
  31. pause
  32. exit /b
  33. :backDoor 学生编号 班编号 [color=red] 错误后门方法 [/color]
  34. for /l %%i in (1 1 10) do (
  35.   if /i "X-%%i" neq "%2" (
  36.     rem find 后是一个含尾空格的查找串 "%1 ", 避免将1位以上的数字错误处理
  37.     (echo !X-%%i!|find /i "%1 ">nul)&&(
  38.       (echo 调换: %1 所在的 X-%%i 班 ^<==^> %2 班)
  39.       set tt=!X-%%i!& set X-%%i=!%2!& set "%2=!tt!"
  40.       exit /b
  41.     )
  42.   )
  43. )
  44. exit /b
复制代码

[ 本帖最后由 neorobin 于 2010-6-27 23:49 编辑 ]

TOP

假设两个后门学生都在一个班呢?
又或者都在3班或8班呢?
1

评分人数

    • batman: 这我真没想到,汗水。。。PB + 5
技术问题请到论坛发帖求助!

TOP

回复 13楼 的帖子

正要说这个, 用换班的方法会造成矛盾,
设换班号之前两个后门生其中一个在 M 班, 要去 P 班
而另一个在 N 班, 要去 Q 班
就存在两次班号调换, M<==>P, N<==>Q
这样, 当 M, N, P, Q 这四个数字中有相同, 但又不是 M=Q且P=N的情况, 就会至少使一个后门生到不了要去的班号.

单单调换学生时, 如果学生不属一个类别, 不会有问题, 如果有相同类别的后门生都要换班, 那么代码须要更复杂的设计
  1. @echo off & setlocal enableDelayedExpansion
  2. for %%a in (A B C D) do (
  3.   for /l %%i in (1001 1 1100) do set "sStu=!sStu!%%a-%%i"
  4.   set "sStu=!sStu:-1=-!"&  set "base=100"
  5.   for /l %%x in (1 1 10) do (
  6.     for /l %%i in (1 1 10) do (
  7.       set /a "start=(!random!%%base)*5"
  8.       for %%s in (!start!) do (
  9.         set "choose=!sStu:~%%s,5!"
  10.         for %%c in (!choose!) do (
  11.           set "X-%%x=!X-%%x! %%c"
  12.           set "sStu=!sStu:%%c=!"
  13.           set /a base-=1
  14. ) ) ) ) )
  15. (echo 开后门之前...)&set X-&pause
  16. (echo 开后门...)&call :backDoor B-060 X-3 11&call :backDoor C-049 X-8 21
  17. (echo 开后门之后...)&set X-&pause
  18. exit /b
  19. :backDoor 学生编号 班编号 班内目标号 如: C-049 安排到 X-8, C 起始于 #21
  20. for /l %%i in (1 1 10) do (
  21.   if /i "X-%%i" neq "%2" (
  22.     (echo !X-%%i!|find /i "%1">nul)&&(
  23.       for /f "tokens=%3 delims= " %%t in ("!%2!") do (
  24.         (echo 调换: X-%%i 班的 %1 ^<==^> %2 班的 %%t )
  25.         set "X-%%i=!X-%%i:%1=%%t!"
  26.         set "%2=!%2:%%t=%1!"
  27.       )  
  28.       exit /b
  29. ) ) )
  30. exit /b
复制代码

[ 本帖最后由 neorobin 于 2010-6-28 00:17 编辑 ]

TOP

为了开这个后门,导致代码又长又多作许多无用功,汗,找不到更好的方法,先凑合着用
思路:
先将400名学生分成4组,再乱序,然后在每班每组按顺序取10个,
并同时记录下后门学生所在班级,再记录下3班一名高等生和8班一名差等生
最后把3班的这名高等生编到b60所在班,把b60强行编到3班
8班也是

:
  1. @echo off&setlocal EnableDelayedExpansion
  2. for %%a in (a b c d) do call :loop %%a
  3. for /l %%a in (1 1 10) do (
  4.    set /a t+=1,w+=10
  5.    for %%i in (a b c d) do (
  6.       for /l %%j in (!t! 1 !w!) do (
  7.          set #%%a=!#%%a! !.%%i%%j!
  8.          set tmp=!.%%i%%j!
  9.          if "!.%%i%%j!"=="b60" set j=%%a
  10.          if %%a equ 3 if "!tmp:~0,1!"=="b" if not "!tmp!"=="b60" set t3=!tmp!
  11.          if "!.%%i%%j!"=="c49" set wen=%%a
  12.          if %%a equ 8 if "!tmp:~0,1!"=="c" if not "!tmp!"=="c49" set t8=!tmp!
  13.        )
  14.     )
  15.     set /a t=w
  16. )
  17. echo 两个后门学生原来所在班 !j!  !wen!&echo;
  18. for %%a in (!j!) do set #%%a=!#%%a:b60=! !t3!
  19. for %%a in (!wen!) do set #%%a=!#%%a:c49=! !t8!
  20. set #3=!#3! b60
  21. set #8=!#8! c49
  22. for /l %%a in (1 1 10) do (
  23.    echo %%a班
  24.    echo !#%%a!
  25.    echo;
  26. )
  27. pause&exit
  28. :loop
  29. for /l %%i in (1 1 100) do set .%1%%i=%1%%i
  30. for /l %%i in (1 1 100) do (
  31.     set /a rnd=!random!%%100+1
  32.     for %%j in (!rnd!) do set tmp=!.%1%%j!
  33.     set .%1!rnd!=!.%1%%i!
  34.     set .%1%%i=!tmp!
  35. )
  36. goto :EOF
复制代码
技术问题请到论坛发帖求助!

TOP

返回列表