- 在线时间
- 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次,也就是说保留一个以外都得移动。
3 c" I, B1 t. \9 z9 v) f$ k5 s; N$ w. M& W e1 j4 ^' u4 V; I8 G* C
另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
# a) d/ \' [9 Q+ I; p0 D. z/ f, R我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:0 M# S% {) b$ N( Z- p6 g
9 }& J4 [( L, a) X7 q: H8 n* O8 ^. N' u1 E1 t2 S" S6 V
C#code:2 `+ g7 G5 e) `6 m% v
private void button1_Click(object sender, EventArgs e); |, }7 n- j% p/ C; ?" i
{0 q/ `) t& G. m2 F/ z
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放0 |2 e! y/ J5 q
// 就可以使所有车辆连续停放( U. @" s, p1 I$ }# P/ A" {
) y# i; u7 V% w
int n = int.Parse(textBox1.Text);/ \( z7 L5 A0 I) g
int x = int.Parse(textBox2.Text);
( n6 t8 z9 y" p) t
* U1 k. I. d: u //500次随机模拟的最接近数字,对比公式计算7 P6 [) }& n o; E4 v
int maxValue = 0;
( N# W+ B5 A: ?% v7 @" F" ] for (int i = 0; i < 500; i++)
; _) Q8 A# B- M. w) @4 l/ K4 C {
1 R+ b0 a* g: R/ [$ \; l0 v. W! \ int value = randResult(x, n);
5 `7 K8 F% q ]9 |2 T if (maxValue < value) maxValue = value;
. ]2 @9 N/ S$ n. Y$ b b lbMsg.Text = i.ToString();
, i: O l6 e2 Z4 y' Y lbMsg.Refresh();. p6 ]' k4 L( f9 r7 m9 H$ E& A$ b
}, G. S4 I4 T, [- w( v
textBox3.Text = maxValue.ToString();
' B; W9 m) r: o" l8 Y
$ n4 ^8 ^( r7 o5 ~" p //这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)
( N! E3 W& e# G" Q. w1 B double newValue = (double)n - ((n*n)/(double)x);+ U8 A6 }- i8 i) [ n- X0 y% j
textBox4.Text = newValue.ToString();
5 z6 G8 j( F7 C* [" {$ R$ ]+ | }
& N/ o- T7 z) Q2 _( [4 f# ]# Q+ U( h- X' d$ N1 _5 ^
private int randResult(int max, int n)
' B) f6 v' P/ j* n0 ~ {
, f; z( }& T( J2 v if(max <= n) return 0; //error
# B) U1 Z5 ]- `" V# V9 Q if (n < 3) return 0; //error, b/ m1 W! o$ B7 V4 N
if (max < 3) return 0; //error
6 w4 K0 \5 K1 T! `6 p! y) H4 M" D% e
int[] lib = new int[max + 1];* p1 t& }) F0 }* |( g
//随机产生数字来填充* @% |9 n+ L! T$ S
lib[1] = 1; lib[max] = 1;
x) f j/ x' y% }+ ~ int count = n - 2;1 S# D9 m: a: N" Y5 ] B. M) C( s
Random rand = new Random();2 N/ J9 A! Q/ Z; z2 @# y
while (count > 0)! z+ u" ?7 a) m9 s
{
1 K2 w! a( l" v& l" G; p3 ] int rnd = rand.Next(1, max);
* S2 w/ R4 P) g) k if (lib[rnd] == 0)
0 V, j% v) m2 D# y {& y5 V& g# o1 ^8 y6 O
lib[rnd] = 1;
( J. ?- ^1 b- { B count--;) p A9 i/ ]" j3 w: Q3 Q. S# o
}9 T# z) q1 J% D/ [: c9 t7 ]) v
}3 i! g: |/ P' r8 C% e* q8 R
//循环检查最密集区域,也就是需要移动最少的区域' J( T0 \4 ~ v0 l4 o! }2 j. f
int min_space = n;% c4 ]; X. B1 y( v% Q
for (int i = 1; i <= max - n + 1; i++)- _7 O& J4 D) }8 D) e6 y
{
, C; m6 k( @: a" H& g* z" N! h int space = space_count(lib, i, n);. S: ]- `8 f0 j: p3 p
if (min_space > space) min_space = space;4 f) l2 A% q: e9 k
}
5 d9 W+ S* ^: r; |/ W# f0 d( ]' r return min_space;% t3 I+ w% m8 O% |; @/ {
}
" k/ N8 Z2 P& A/ d* Q' @
: b8 P' i, ]7 K( P7 {: n0 U private int space_count(int[] lib, int start, int n)" s, M% t* I" _- Z' g& @
{ //检查数组start后面n项数据里面有多少个1
6 f2 B! o1 C+ y& V' q2 _$ _ int count = 0;
2 N, u, P, l$ G: w$ m0 n for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;
% T, z" |. x7 u( R. L8 x# x return count;
0 u0 x, V- e& p' C }2 V6 \+ B# M" \5 E- K9 B% k
|
|