- 在线时间
- 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次,也就是说保留一个以外都得移动。
7 B9 ~: X3 Y7 c/ r- b
" U% V" L: q. t) S$ ^1 n1 }另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
8 ^ Y- @! W# T1 W我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:
8 H$ y0 m! n+ a$ _
# C8 F! H I% o! P7 T6 @/ V) z5 O
* W/ K. z a5 n% y( dC#code:4 B1 j, ]7 T* m: u
private void button1_Click(object sender, EventArgs e)* u9 U5 c1 P; M- }' A$ R# J
{3 ]: A! [& Q+ [$ Q
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放( U. n/ l3 L* Z Z4 r3 H
// 就可以使所有车辆连续停放
; f; ^4 t8 N$ N' i$ Z
$ I1 h' K" j! U1 M2 w1 @ f4 T int n = int.Parse(textBox1.Text);
5 |( X8 i' {7 `( w int x = int.Parse(textBox2.Text);$ q% D% ~) @) d% Q- P8 ?
3 N5 @4 Y! U; N# w5 P! _ //500次随机模拟的最接近数字,对比公式计算. M I9 J- F9 i2 g; v
int maxValue = 0;0 n9 P1 w% O8 W; ^, ?
for (int i = 0; i < 500; i++)
8 w" h( X, H8 A* v+ @ {
8 Y& a+ X* z! |* b int value = randResult(x, n);' U7 Z/ P% u1 ]' N
if (maxValue < value) maxValue = value;0 u; i' o4 `. W) J
lbMsg.Text = i.ToString();
; V3 D% |' g, L$ _1 r4 V/ _ lbMsg.Refresh();6 s+ r% ?& J5 _
} ^" s1 J1 k5 E5 G2 y
textBox3.Text = maxValue.ToString();8 E8 q5 Z2 j* i0 R; _3 K, W$ v& i
7 I1 K' ?3 o- d
//这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :): W5 {: ]" @. j! u) e6 r7 E! e
double newValue = (double)n - ((n*n)/(double)x);
% L p( F& M2 z$ A+ P$ x textBox4.Text = newValue.ToString();4 v( y$ \3 Z- q9 l3 {% |
}
6 `, ?6 T8 K% _" M8 J% `" k# p# b$ P" O8 {
private int randResult(int max, int n), _2 |" {: K4 W! E) ?! u, Z
{
w! ?: T. n! Q0 H: f if(max <= n) return 0; //error
h* R4 v; l7 V7 d# L9 A if (n < 3) return 0; //error
0 [4 y, j% @* Z% G- F if (max < 3) return 0; //error: j1 P/ Q7 r5 i$ @
+ H* E* V* ?) e' K3 W
int[] lib = new int[max + 1];+ l9 { d$ p9 i
//随机产生数字来填充
; T# S% o2 |; K( m' d6 Q: O lib[1] = 1; lib[max] = 1;
6 S% x7 |: X; b$ k* i' @( q( m8 P int count = n - 2;7 o/ ?& @. O% o+ y' M
Random rand = new Random();1 S6 f* G; i( w, e, N0 S% q' j: I8 `
while (count > 0), A2 M0 `6 a2 x
{ T; b$ j; B2 `6 L+ x
int rnd = rand.Next(1, max);' d6 k9 l1 b1 j- _5 H
if (lib[rnd] == 0)
+ ^0 n3 F5 X( p& R4 A: p- X. D {
2 X5 G9 z5 n1 P& \ lib[rnd] = 1;
+ w" D3 ?8 ?& Y$ y$ _0 O count--;
, G+ y' @. S) H1 x }
2 \1 }: q: |7 Y" o7 x3 v8 T. D }
$ z7 G9 }" I4 v) h5 @6 P //循环检查最密集区域,也就是需要移动最少的区域
- u9 k2 y; g- p: F! S. _( p( c int min_space = n;
' }* I# Y; o. K# o for (int i = 1; i <= max - n + 1; i++)+ C8 b, o) f+ C4 j8 Y
{+ b" W1 U: p5 S+ D0 ~+ q2 x
int space = space_count(lib, i, n);
: j9 ?8 a5 D& U* E4 w if (min_space > space) min_space = space;
9 l3 I! B* T U1 b }% x; s( {- m# k6 x; _4 M% p. p
return min_space;; z; P5 _' j' N2 |6 s B
}
/ ~2 s+ R) u" ]6 R
9 w( |2 S& z/ m8 p private int space_count(int[] lib, int start, int n)
5 L7 `1 t( U4 k V- k- N { //检查数组start后面n项数据里面有多少个1
5 d- g1 Y& r+ T int count = 0;1 ^" Q- ^6 E1 V- a
for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;0 M* e* H1 s4 [ a8 C
return count;! f3 M# l, W9 z1 M6 l _
}8 h# B3 u# l. l m+ U# v) `5 s0 P* d
|
|