- 在线时间
- 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次,也就是说保留一个以外都得移动。1 F$ x- H+ J3 K& g4 `* d
0 t' N7 e6 X5 p2 L9 y: Q
另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
7 t& T x, [, u* {我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:6 z* O/ X' M6 Z; E/ }3 w
1 v4 Y& I( w7 k1 l
/ v3 @/ J5 s% O( n wC#code:
|& M) v7 R% Q6 A0 D9 l3 ~ private void button1_Click(object sender, EventArgs e)! p$ e- Y0 L Q2 [, x/ x
{ v3 _8 }" G7 U" }
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放0 R. Z5 E$ h( f6 w9 z( e+ R
// 就可以使所有车辆连续停放
3 K F$ H" }( R' v3 O# L' c! h
. m0 w5 y$ [9 k" D* C int n = int.Parse(textBox1.Text);
1 @+ f: O5 X; {- T7 H1 K ~ int x = int.Parse(textBox2.Text);
: ?4 J3 E3 h% f# O/ ]3 h. t
! d) k: U! T6 h( n# W/ Q //500次随机模拟的最接近数字,对比公式计算+ @" p8 J; |3 M1 V
int maxValue = 0;
. E2 A2 o; F# }7 \" G E5 k1 W7 a for (int i = 0; i < 500; i++)
4 [+ \- ^* A! Q, y" P% D- g! Y {9 q/ a1 I! X, L0 n# G# l- |4 d
int value = randResult(x, n);0 W( q; x$ A. L" W f e6 N
if (maxValue < value) maxValue = value;
+ k; A+ U0 c/ c" W& F lbMsg.Text = i.ToString();: D3 c6 r/ F2 `# P) N( [
lbMsg.Refresh();) }( V6 j$ {& _# Q$ a( y' A; q
}
8 ]5 V$ @6 S, g3 @8 y+ h textBox3.Text = maxValue.ToString();0 F' f" c6 n$ A4 _
; j4 I% L5 O$ P" z
//这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)! S$ k1 i$ w; r( p# d
double newValue = (double)n - ((n*n)/(double)x);; e; n# \, I' j4 a! h) _' [, m
textBox4.Text = newValue.ToString();
$ h" K6 I- p/ w2 i- N, l }8 z* F% _. e, Q0 @! v
4 A( @# B5 [3 W private int randResult(int max, int n)/ w0 s! W5 \* ~7 C
{
: q* c8 f0 u4 U+ n. f if(max <= n) return 0; //error
( y/ x. E8 v( f3 `3 [ if (n < 3) return 0; //error; o3 u) l2 f$ R) s- v5 n- T4 ^; r
if (max < 3) return 0; //error
9 q' y s. l4 e0 L, b* x% J. S9 H* ?, O
int[] lib = new int[max + 1];8 [- L9 V4 p/ W+ S
//随机产生数字来填充
j. i+ q; e9 q* ~$ E8 Y- ^ lib[1] = 1; lib[max] = 1;
- ?, }* j% H" X5 ]5 W int count = n - 2;( Z. [ R3 X6 y! _, I
Random rand = new Random();
+ o+ G5 o# Q8 o while (count > 0)3 @& X4 c' t+ p2 B. p7 e$ d
{) A( X3 i& ?, G& ^; K; I
int rnd = rand.Next(1, max);- ]3 G& n+ U9 ]0 ?% R* h
if (lib[rnd] == 0)$ F1 N2 E: q6 _* A$ w7 R4 Y4 Z7 r$ ^
{& ~# W I6 z& E, R/ ~+ n# [2 y
lib[rnd] = 1;; s& ~: h4 z# T2 a: F
count--;& @# b$ }& V9 R b
}1 d G, f$ A# T8 p
}7 U+ w7 S A4 B* @8 R
//循环检查最密集区域,也就是需要移动最少的区域
3 U6 |9 [' h% ~& `$ s- d6 l+ x% A2 R% x int min_space = n;1 D: y9 r: M" o* C
for (int i = 1; i <= max - n + 1; i++)
! O6 Y2 Y( K: W {& x6 \3 z. d5 n
int space = space_count(lib, i, n);
, a" p6 c9 E2 R" k if (min_space > space) min_space = space;) [: l- p8 d% ?8 H |' I0 i
}
( v O. o5 S9 l return min_space;4 \ C9 w1 r$ {9 C+ c0 L0 g7 i) L2 f
}- o/ c' C1 ]2 @. d4 a) ^6 K- |
# {; z+ X' |0 o7 _0 _/ K7 U+ x private int space_count(int[] lib, int start, int n)
- C9 F. y8 v" S0 x+ \! W5 S u { //检查数组start后面n项数据里面有多少个1
, l6 h5 D: z6 {. J* d) `& ~ int count = 0;
+ f0 ]3 L( T% e1 E4 S; U for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;7 W. w% U' g' c m+ ?3 I0 Q
return count;) P0 s7 H& c" [. n+ {3 k
}
% g- h7 t; y0 Q5 _: w |
|