- 在线时间
- 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次,也就是说保留一个以外都得移动。
" z0 ?/ Y9 L, z4 S' H* U; l9 n$ L; `, [5 _$ E3 w- A
另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
' N% B4 |7 m& Z- }我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:
4 N2 l" Z+ m t$ K, n8 y# X# n3 ?; s( i ^9 ^0 S& ]
8 T$ s& E/ W5 E: MC#code:
' R2 X( x( ^! W, m+ G0 Z" c" t2 \ private void button1_Click(object sender, EventArgs e)
# @* ^/ j( `/ u" I. [! V3 G y {3 C) C6 O! ~4 k8 b4 A& q% c8 G
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放
1 _6 x* T' {( n9 ^4 ~& i- A$ \6 j // 就可以使所有车辆连续停放9 b Z0 ?$ g/ x1 H8 V; ~0 w
! m. c" _, l% F3 |, A- U0 g, J
int n = int.Parse(textBox1.Text);
) D; e4 e5 s" u0 d N int x = int.Parse(textBox2.Text);
% O$ ]+ c- X" h) u) u: ^; q. q# O. y2 `0 O4 C; Y
//500次随机模拟的最接近数字,对比公式计算7 p$ ], C ?: M+ Y
int maxValue = 0;
K) v5 G$ b5 x4 {( A for (int i = 0; i < 500; i++)3 K4 ^: w$ W6 K- X/ O
{
; M, j5 r; g4 q3 } int value = randResult(x, n);5 E) ^. L8 K/ A- y! g* ]5 h4 m7 R4 F
if (maxValue < value) maxValue = value;
( y8 T" \% o8 J# Z: Z7 z: _ lbMsg.Text = i.ToString();
* u. s: R& u, g V lbMsg.Refresh();6 C0 Z! _5 V8 M; [6 e. | v
}
0 a+ ^$ U( N# ^9 V' Q5 M7 C textBox3.Text = maxValue.ToString();
% A( k$ |6 p- I
9 q4 w) @% z3 C' K5 N5 h. N //这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)3 { n7 V' d: Q& a, _& H
double newValue = (double)n - ((n*n)/(double)x);) S3 a5 g4 V `
textBox4.Text = newValue.ToString();
# a" o" G8 I- `6 p4 e4 m }
$ }0 n8 Q* v- j! R* T& P% m }4 [0 U# k+ l5 \
private int randResult(int max, int n)
/ W$ Y8 l$ a; U* W% V5 G% ? {. `5 K8 T3 i4 I3 B2 F
if(max <= n) return 0; //error
5 T: |; n/ [# K$ Z O7 M: {/ R6 w; u( _ if (n < 3) return 0; //error
. R a' I# ?/ N" I c X if (max < 3) return 0; //error
, E |5 F; j x* v3 } v* |/ I
0 P* R4 w1 i- @7 y8 l) s: A int[] lib = new int[max + 1];+ J& S2 q0 F. ^# B% p2 h" z
//随机产生数字来填充
- d! Z/ D- s6 h lib[1] = 1; lib[max] = 1;
# c& j0 z$ {& H9 f. m int count = n - 2;
, W- N9 Q; ]* _' P2 _4 t Random rand = new Random();
4 A9 L# T" y1 E3 s# W while (count > 0)
+ J% R& d0 y5 w8 N! T {
" i0 G# j7 S) L% j* h! y: a$ O& A int rnd = rand.Next(1, max);
5 z+ q5 i2 @2 e* `' |# i8 }8 S if (lib[rnd] == 0)0 G- ]% `9 ]2 V# W5 w$ o8 h) {6 W5 m
{2 {3 C) q" S0 h8 J
lib[rnd] = 1;
# h5 W: i, n, N3 z6 N5 d count--;' w) S$ P$ `- ?3 ]% J: U: N
}0 m+ d4 j2 ~* d; x% O9 T
}
6 T. B- ~* C, _: U. t //循环检查最密集区域,也就是需要移动最少的区域
, D1 l4 F$ A- o- G7 x# K int min_space = n;+ v, W3 j2 w: R) X
for (int i = 1; i <= max - n + 1; i++)
9 b$ l0 q1 q* R% } {
# f) Z2 e) i7 {: s. J: O0 x int space = space_count(lib, i, n);
- q. P9 @! N( c if (min_space > space) min_space = space;
1 m' n1 H. m2 h. Q- J }3 N9 y- }& [ Q$ n( ^* ]; ~+ U) k& B
return min_space;9 v2 w) Y. t. Q* a
}
" @& t; T5 [% C* N3 W8 Z
2 [5 [' O8 I5 J9 n private int space_count(int[] lib, int start, int n); w5 d$ E" Z5 A9 W) T
{ //检查数组start后面n项数据里面有多少个1! Z& Z1 s: E* L& W! i1 c7 ^2 N+ O
int count = 0;
. ?# V1 l6 k! C2 V b& u for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;" K, i$ [. r( g$ R; s0 o. D: L2 p
return count;
& d3 W5 E$ S1 y) F& u0 u# B+ A* W }
3 U) `7 k- I2 i: P$ _6 p8 | |
|