- 在线时间
- 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次,也就是说保留一个以外都得移动。
' Y- p. {0 v8 g: Y) u; B- W9 w: x0 {
3 M u; d% a0 q& V1 ~) J另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
1 P y- q9 k. g5 g9 i, I% o我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:" u! m' d. I6 e4 G: c8 s
9 H# z6 r3 g$ ]2 D
. v3 U1 m7 V* V+ YC#code:
% M$ C2 v4 P* S' }& w( I private void button1_Click(object sender, EventArgs e)
1 I) H/ f& v) f* G {5 h: j0 s5 V% h, A% ]2 j' \8 n. v
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放
" q ?) e0 i0 V+ q // 就可以使所有车辆连续停放/ @8 e$ k& B$ T0 x3 N& a
9 l# d. P* t: a int n = int.Parse(textBox1.Text);+ j$ l# K2 ~+ T5 y
int x = int.Parse(textBox2.Text);
8 W; x0 s0 M" ]3 Q8 N+ O% i2 }1 _% z y( ?
//500次随机模拟的最接近数字,对比公式计算
6 R: U" S5 J1 p) b8 M6 a int maxValue = 0;
X9 t9 u. l" o% m for (int i = 0; i < 500; i++)
* c8 q& h7 E3 o1 a( ] {
% |: v! V2 f; o$ P* I8 y int value = randResult(x, n);
) b* b! G1 I+ E# Z! Z# C if (maxValue < value) maxValue = value;# C' X- u6 M8 E1 n
lbMsg.Text = i.ToString();7 O/ H/ J" w5 V: U
lbMsg.Refresh();( Z, p3 L1 Y3 n7 m& C) f1 A
}
! X# c Y: k9 T& L) T5 j textBox3.Text = maxValue.ToString();: D4 \ h8 w8 t2 W
4 V9 W% n; r" ?4 P //这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)
% I. {: C: p3 D( ~; m double newValue = (double)n - ((n*n)/(double)x);. g5 U: \" Z B% O
textBox4.Text = newValue.ToString();
) [; i" }& J- ^- O+ e& o0 q( | }# g8 P% [! |% }( j6 r) I3 ]2 R: o
4 a" S/ U3 a7 h% B private int randResult(int max, int n)! [ O& S4 s. L' E& d P! }
{
5 l6 \, K$ _+ L, k, a8 }* O+ x T if(max <= n) return 0; //error
8 T+ v, a- e, d' ^6 r) t" v if (n < 3) return 0; //error j/ Z0 H8 V9 t; G) M# K
if (max < 3) return 0; //error
0 \6 _1 ~/ `" `; p' C, j
4 P/ I/ L5 B8 e* h: Q; Q6 @5 U# y int[] lib = new int[max + 1];
4 F4 N$ g* ^0 b( E; C/ [& U) s0 z //随机产生数字来填充
9 f- k* F" f8 A6 y$ N9 V: }$ L lib[1] = 1; lib[max] = 1;
) p/ C$ U! I1 z* {0 A) Z: ]" u int count = n - 2;+ A, V$ n; t& S" L4 u5 ^- o
Random rand = new Random();* y2 k5 ?# z& L
while (count > 0)
" g' }' @5 M. p" s0 Z5 K {
+ c8 T7 \) s# l int rnd = rand.Next(1, max);8 y2 n3 X0 u9 {; z7 h
if (lib[rnd] == 0)
4 B* u$ {) Z$ b. J9 m5 L {
- H+ O( ^* [& \' f lib[rnd] = 1; O5 y# ^3 p9 X ~
count--;1 H0 d' L2 m3 f4 F
}
0 q: t0 N! r; _6 H: l. ?. D }
W. X$ X" S. m" H //循环检查最密集区域,也就是需要移动最少的区域
; Q/ U4 H: {1 C5 M8 K int min_space = n;
2 I6 u! e8 U8 ^4 Q, B3 v for (int i = 1; i <= max - n + 1; i++)% d" [1 {5 z$ I+ m
{
: c1 f9 a+ ~ B8 n8 f$ G- V int space = space_count(lib, i, n);
|# Z8 T$ s& H+ B' J' Y if (min_space > space) min_space = space;
' [5 Z2 g0 v O" f2 ^1 k }
0 M' Q+ {+ S/ t: }# u' f3 P ^8 D return min_space;' b4 c5 D, \ S* ?" k. D& r
}6 O- H1 y( w/ V1 [6 M+ O
" C! Y! c. i7 T
private int space_count(int[] lib, int start, int n)
3 y, p6 F1 L4 P+ M: W8 b3 l$ H- d { //检查数组start后面n项数据里面有多少个13 o+ t- E; H8 I4 W
int count = 0;
, Z* u' R/ P# D for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;
# K- `9 {* J- l return count;
8 r5 @$ L5 U, J7 i# b }
5 e* ^9 V' }6 N- j9 v3 }) T |
|