- 在线时间
- 2 小时
- 最后登录
- 2017-8-7
- 注册时间
- 2010-6-27
- 听众数
- 2
- 收听数
- 0
- 能力
- 0 分
- 体力
- 40 点
- 威望
- 0 点
- 阅读权限
- 20
- 积分
- 14
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 3
- 主题
- 1
- 精华
- 0
- 分享
- 0
- 好友
- 0
升级   9.47% 该用户从未签到
|
已经能够确定的是:如果 x > (n * (n-1) + 1),表示密度太‘稀’了,这种情况下必然是移动 n - 1次,也就是说保留一个以外都得移动。5 g/ B7 `+ H3 c% A+ q
: l' H' a2 F- V3 C另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
0 j- S$ e: y" F* M: m" U我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:
" {% t" x, K& @7 E5 b
9 [, T! r5 O/ f6 Z4 F! n$ e9 J2 L- s ~/ ?/ s# u/ s) T m2 C
C#code:4 _7 S# m4 _% J/ F8 |7 r
private void button1_Click(object sender, EventArgs e) ?" c ?7 _' E
{! W; Y; N7 n" c
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放
5 @- g/ m7 l, b- ^5 @1 d1 S. \ // 就可以使所有车辆连续停放8 [. G3 {0 q) m8 h
0 T5 A! U* G6 Z* |3 q0 s# w
int n = int.Parse(textBox1.Text);
# q3 b: i: X5 k: T int x = int.Parse(textBox2.Text);
; m: K9 N' |4 P! p( L0 w5 q
4 c4 ]2 C$ F1 [: M7 H' T //500次随机模拟的最接近数字,对比公式计算+ P D# h d5 S* p( ?4 N
int maxValue = 0;
; V4 z3 K5 g3 h7 O7 X8 A for (int i = 0; i < 500; i++)0 G3 K$ \# N% E( s1 I8 w' n
{! s( J. r2 Y/ j: o5 ~+ W0 f; C
int value = randResult(x, n);
+ m% R% I3 A3 |- j% G if (maxValue < value) maxValue = value;
8 I7 \4 x3 e1 W) T d lbMsg.Text = i.ToString();
" G( s; A8 y" Y) O9 w0 `+ l, m- n lbMsg.Refresh();4 F: f8 \; ^* L% W
}. D) r, i% P$ ]. Q6 I
textBox3.Text = maxValue.ToString();
: ?* d* q( _( r3 x$ y
& o q; A* C. U' C, P& S6 h% w3 o4 j //这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)
7 P3 L' F+ c6 C8 D0 G5 } double newValue = (double)n - ((n*n)/(double)x);7 L9 i9 [5 O6 o" a- z* O
textBox4.Text = newValue.ToString();# a# Z. b0 w! k2 ^
}
t4 O! p" h8 T
, j* ]6 Y: Y0 w7 {& v* c private int randResult(int max, int n)
& {! W$ D/ C2 W# d6 @ {) d! u" F' x$ |7 C$ P. B6 _
if(max <= n) return 0; //error7 L2 B* V9 ?) Q3 ?& W
if (n < 3) return 0; //error
& f. ?: t( J8 y! b' J if (max < 3) return 0; //error$ p7 [/ ^+ G0 {8 s4 k2 D+ O
5 Z T: P4 e+ k, M0 z; |% l# t2 n
int[] lib = new int[max + 1];9 G- }7 m" m2 u$ O
//随机产生数字来填充
+ O# {/ \: @5 [8 [9 z lib[1] = 1; lib[max] = 1;
. s& ^# N" N5 n. Z. @! n int count = n - 2;0 a1 o9 F1 d) E
Random rand = new Random();
3 p: ]/ o! a' ^; B. x8 [% c/ h% ` while (count > 0)
+ H" a. y6 Y' a7 t& W7 @. n. x {: `4 ?( }6 i, F! D8 b# y
int rnd = rand.Next(1, max);" ~- l) w* `* a; j2 }
if (lib[rnd] == 0)
/ R7 Z7 T! q2 d {
- c( O8 j# I! I" G% v! A lib[rnd] = 1;
& M: l6 ?9 f4 L% C; D2 d count--;! i9 W' T$ i; R4 c! ~5 `
}
: u! r5 B; U" P- Y. I }9 [' |. H4 h U( K
//循环检查最密集区域,也就是需要移动最少的区域
& Y* X2 U' }: i) t6 c$ @ int min_space = n;
+ @1 b4 p. |- O& f, ^: s for (int i = 1; i <= max - n + 1; i++)3 D& L0 f* w8 h4 {, F6 }9 n) Y
{) W6 D @9 z. x: ~3 _% f
int space = space_count(lib, i, n);
/ }( O0 W/ [% P p if (min_space > space) min_space = space;
# Z9 L5 J; O/ F& Q$ g& P }
) }# Y. v7 r' P) s+ E y1 t return min_space;9 x. j' v- K7 g
}( c t7 g1 I3 j3 P# B! T
K" l- ?) p S( ]" C/ k private int space_count(int[] lib, int start, int n): x6 M8 B' ~6 C6 o2 J7 J
{ //检查数组start后面n项数据里面有多少个1
B& U; p1 }3 v; c* P int count = 0;
5 g$ S" P& p+ `" g1 T for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;1 M1 O% Q8 g1 A7 v# N. A
return count;+ k7 I6 V; q' p% Z) I) z
}, L z1 P4 i1 K6 O7 {
|
|