数学建模社区-数学中国

标题: 看着车牌忽然想到一个题目,几次变化使之连续 [打印本页]

作者: trytoday    时间: 2010-6-27 15:46
标题: 看着车牌忽然想到一个题目,几次变化使之连续
看着车牌忽然想到一个题目,细一想还挺难,不知道是否属于数论分类
9 z# Y( J8 q% Q- ?% U' w, ?+ \' Q, Z3 {  G3 n/ j

8 ?6 y/ h; p) `& }, S比如车牌398276,需要两次变化:把2变成4,3变成5,就成为完全连续的数字了。推广开来,一共有n个不重复的整数,最大不超过max,问需要最多几次变化可以使之全部连续。' P  P+ e  l/ F5 C- H" A

9 @5 d+ C& L, i6 D例如上面车牌:n=6个不重复整数,最大不超过max=10,需要最多3次变化使之全部连续。
作者: linmatsas    时间: 2010-6-27 16:24
是最少需要几次变化吧…………
作者: yupo_smart    时间: 2010-6-27 19:25
想法很好,可以好好考虑一下。
作者: trytoday    时间: 2010-6-27 21:49
已经能够确定的是:如果 x > (n * (n-1) + 1),表示密度太‘稀’了,这种情况下必然是移动 n - 1次,也就是说保留一个以外都得移动。
7 V$ i0 g/ H$ E; Y# |8 p* o5 O
) i7 Y/ `$ A: c- j' h* [3 T  B另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
& B3 c/ X5 Y: w, k2 r1 M) x; X7 s我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:
) Q% |4 k3 O, w& w. `! {- K
. x6 k! M) }, S' @0 B9 ?" k  L# }" p, }  o- S
C#code:
4 P9 U! }. L5 V: Q                private void button1_Click(object sender, EventArgs e): r# e4 ]- q- L* ?, d& \
                {- o) j0 O1 L6 E$ J- h
            //新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放  K5 z8 l& ]- A* a) V8 O
            //          就可以使所有车辆连续停放: _) a1 ?& H) ~& n
            
0 C5 Z+ d2 {0 S) Q. W3 N' `            int n = int.Parse(textBox1.Text);- `* C' |% m0 d9 p% `. N+ R
            int x = int.Parse(textBox2.Text);
1 f  N# b- X/ ?% a" q; k% c2 P6 j2 U6 |& K0 ]5 S
            //500次随机模拟的最接近数字,对比公式计算' ^- v+ \9 H. H4 j; Q9 K: v4 X
            int maxValue = 0;/ a- k0 C+ N9 W, v! P' u0 ^
            for (int i = 0; i < 500; i++)
7 a- l. y! O  P0 r0 `" ?6 B+ d$ G            {
, R8 m. A2 Y1 o0 _% b* Q5 W                int value = randResult(x, n);
4 e  B* v  d7 m, p& c                if (maxValue < value) maxValue = value;! L! _4 U# ~8 e7 J' R
                lbMsg.Text = i.ToString();' s; S: s: Z: y8 x. Q8 f
                lbMsg.Refresh();
% E5 H& `/ |( v2 a1 a! {            }7 w% H1 `2 t2 a& n1 y
            textBox3.Text = maxValue.ToString();; _, d/ m) i# Z# d

# @4 y: p" t8 v% q) l" t            //这是公式计算的结果,据观察大部分正确,少数误差也不超过 3  :)
, h+ ?; s/ ?! q& {+ Q            double newValue = (double)n - ((n*n)/(double)x);
+ k+ W9 C/ V' P) U6 P            textBox4.Text = newValue.ToString();4 a: k2 H& m8 k4 E$ {* I: s) G6 ]
                }
8 N* g7 {, u7 P" {$ o) u9 K5 Y! L- p0 @9 a
        private int randResult(int max, int n)# O" ]6 W- F# _& |8 N1 h
        {$ w2 Q" c& U8 J# s
            if(max <= n) return 0; //error& \4 |! x0 x2 E
            if (n < 3) return 0; //error
7 \9 U8 \7 a) h, q$ c" Q' [5 a            if (max < 3) return 0; //error
2 W/ Y3 Y6 C9 B, k0 s: Y: u- s
& G7 O* I1 P1 j  G            int[] lib = new int[max + 1];
$ z7 Q. y( @5 E- {            //随机产生数字来填充. t& B' e* i  w3 D2 j1 B: Q; _; ^
            lib[1] = 1; lib[max] = 1;
+ q9 l/ m6 ^& n4 ]1 t$ y2 ]            int count = n - 2;8 O' f4 l7 |6 J) c
            Random rand = new Random();. A6 G! V: }) K- ]: D* I% X
            while (count > 0)
* u1 U( Q8 g: ]( P) g9 \5 M" z            {
! j2 g5 H; e0 e9 m! g                int rnd = rand.Next(1, max);7 p! @7 }( u8 X7 q: j( K" n& r
                if (lib[rnd] == 0)2 u6 X/ {" j& d" v& q2 Q
                {' C8 b# f  f; y& \3 T, x
                    lib[rnd] = 1;9 h* u3 G* H) o+ v
                    count--;
; W( Q, I" p# C& S" q! P' j' z& }/ M% L                }
, Z# P2 m9 \- f6 O            }
4 I% I& T( V0 f. K9 y  p            //循环检查最密集区域,也就是需要移动最少的区域
/ u; C% A1 H0 h6 o' S            int min_space = n;$ [9 |7 _4 W0 i* ^0 h8 n
            for (int i = 1; i <= max - n + 1; i++)# i4 y( K' g: a: W) F5 T- \5 O
            {
8 j5 w4 t7 {" q3 g, y& N& F  I                int space = space_count(lib, i, n);* U# r/ _' F% f  ~5 u
                if (min_space > space) min_space = space;
# r, ^5 a3 z/ l            }
) S, |* D0 O, u            return min_space;& P* ]6 j; a$ m2 \- Q' s8 d0 v
        }
2 G' T8 p* b! P5 h+ G1 k* @
# C* |  \3 S5 R/ R9 K        private int space_count(int[] lib, int start, int n)
/ ?8 i$ U0 S' c, o        {   //检查数组start后面n项数据里面有多少个1
, P9 I! ^- m0 v$ o4 n* _" K7 l; ^            int count = 0;: d. V2 c# P' B
            for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;; }) @2 `8 F, r( u/ D  B8 B
            return count;
9 f4 S8 P/ Q) B+ \        }
. O3 g' N! A5 Y8 D. X& t
作者: bingcheers    时间: 2010-6-28 12:53
回复 trytoday 的帖子
# ?+ j2 N7 x% X0 L0 x
3 g( I+ c$ [8 X" {2 v. J( o8 ^& B* u5 V. J
    牛牛,    牛牛,    牛牛
作者: trytoday    时间: 2010-6-28 22:09
问题已经被另一位高人解决,请参阅:1 s9 d! z8 h- z  M! Y
http://topic.csdn.net/u/20100626 ... d-0495bbbb15fc.html
作者: 角凳    时间: 2010-9-7 20:20
好像不是很有意义...




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5