数学建模社区-数学中国
标题:
看着车牌忽然想到一个题目,几次变化使之连续
[打印本页]
作者:
trytoday
时间:
2010-6-27 15:46
标题:
看着车牌忽然想到一个题目,几次变化使之连续
看着车牌忽然想到一个题目,细一想还挺难,不知道是否属于数论分类
: {1 o8 G5 z. c% U; n( f; I
2 o( Z5 c$ a' d+ z6 a
, T! P3 x7 \ j e' v3 V7 g
比如车牌398276,需要两次变化:把2变成4,3变成5,就成为完全连续的数字了。推广开来,一共有n个不重复的整数,最大不超过max,问需要最多几次变化可以使之全部连续。
8 l, t. T1 E% O. w4 ~; m
`. a, S6 k5 N% w
例如上面车牌:n=6个不重复整数,最大不超过max=10,需要最多3次变化使之全部连续。
作者:
linmatsas
时间:
2010-6-27 16:24
是最少需要几次变化吧…………
作者:
yupo_smart
时间:
2010-6-27 19:25
想法很好,可以好好考虑一下。
作者:
trytoday
时间:
2010-6-27 21:49
已经能够确定的是:如果 x > (n * (n-1) + 1),表示密度太‘稀’了,这种情况下必然是移动 n - 1次,也就是说保留一个以外都得移动。
- x/ }: W6 m$ s+ O
: `: ^/ W2 X c/ A" `
另外发现一个简化公式 n - (n*n/x)。用这个公式计算的结果在一些情况有少量误差。
( a( }4 | x/ {, q" {! L
我也没有标准答案来判断误差,只是用随机模拟的方式,对指定的 n x 随机几百次试验确定最有可能的值,以下是代码,效率一般,但n在1000以上几百次模拟也能在几秒内搞定:
p+ \; A% E4 y& ], C0 j& B6 \3 J
' U* H4 h. E2 p0 M
$ F, O( t4 w5 T- [7 v4 ?
C#code:
& `9 [; k0 ~ F) }: u
private void button1_Click(object sender, EventArgs e)
) V! P7 V% n; h$ _
{
) R' J$ H. s$ y
//新的描述:编号 1 -- X 的停车位,随机停放 n 辆车,无论当前车辆怎样的位置,最少让多少辆车重新停放
% ^. B A3 l5 ]. z. j: m
// 就可以使所有车辆连续停放
1 S- f# v% n! i! j/ @5 X5 c* X1 Y
8 e7 m" v$ j/ W- k9 ?" X+ ]
int n = int.Parse(textBox1.Text);
* b5 b9 _1 Q8 r% @& P- F/ J1 ?
int x = int.Parse(textBox2.Text);
( g- {- h- K1 A4 u' U# L' i0 a
) z: p2 }6 E0 D# \4 x' E3 K! _
//500次随机模拟的最接近数字,对比公式计算
$ z# y6 |7 y& |! P
int maxValue = 0;
, I9 B, ?1 M) k9 f* Z. O: \( C
for (int i = 0; i < 500; i++)
3 _ S$ G% s/ H0 A7 `% t
{
) {* p0 q) q i9 ]0 |
int value = randResult(x, n);
: L h# ]1 t; N( Q$ F2 T! E
if (maxValue < value) maxValue = value;
$ [) ^3 r5 P7 r. b
lbMsg.Text = i.ToString();
/ K) n' z: |+ T* x6 V, }& L
lbMsg.Refresh();
/ @8 m5 x( e: R- b0 ]7 {
}
. W, f' Q' T5 P9 W, j
textBox3.Text = maxValue.ToString();
* o* W& N3 y! I2 O1 W5 k
: Q5 \& ^6 w+ u+ e& E5 x
//这是公式计算的结果,据观察大部分正确,少数误差也不超过 3 :)
0 U, F5 W" a# a
double newValue = (double)n - ((n*n)/(double)x);
1 x- w9 j4 M0 a: P
textBox4.Text = newValue.ToString();
& D8 H0 o/ \1 C7 ~3 F3 K7 h
}
0 d# c* M6 ]$ I/ i
' }' j9 _1 \9 w7 B
private int randResult(int max, int n)
! N# E- O2 H2 N* z8 C9 z
{
4 n4 U) }6 U5 R6 e
if(max <= n) return 0; //error
; u3 _6 t" {1 a) k( I
if (n < 3) return 0; //error
" \2 e$ Y' |. d' N O
if (max < 3) return 0; //error
, R4 ?) f: B0 l7 @
. {# A) E0 f( W, @
int[] lib = new int[max + 1];
2 s7 l, m7 D& Q# a
//随机产生数字来填充
G( ^7 G. J {# q4 S9 i6 c
lib[1] = 1; lib[max] = 1;
- B; V" ^% w5 m5 u
int count = n - 2;
( p% X5 d( A/ ^7 v1 f/ M' j3 t& u
Random rand = new Random();
+ u# G+ k Q1 L9 h0 N
while (count > 0)
* l9 Y3 X4 O1 }% M
{
: ` E e: k$ w+ P9 E* s% }* U
int rnd = rand.Next(1, max);
/ H" K1 w% C# @
if (lib[rnd] == 0)
0 q' z8 g, @2 X
{
/ p( N5 Y& z% d
lib[rnd] = 1;
/ D# E# K4 }. N1 Y( h
count--;
: @: d7 n, J$ b. B' ^* J
}
5 A7 G/ n8 E( ]( ^3 L- `
}
) {6 \4 L( y% H6 F7 g
//循环检查最密集区域,也就是需要移动最少的区域
0 u' g* u4 c9 q+ s5 x2 A% v
int min_space = n;
5 o! T! y, e. B9 U7 i# A8 @# T: F
for (int i = 1; i <= max - n + 1; i++)
( _8 U+ A8 `! e7 p0 D6 v
{
8 w" ?( X: J* q! U; E
int space = space_count(lib, i, n);
4 u( r- j1 Z9 I+ z3 f# v' z0 V
if (min_space > space) min_space = space;
$ U9 C6 c- K$ x. K5 N& c
}
( V: s5 P" @* B9 n/ L
return min_space;
* H! X* g& {' a& V6 J! o5 w( ?
}
1 c9 D6 E/ w6 Q& X% ?; E
+ D8 K4 U( {& Q! H2 |
private int space_count(int[] lib, int start, int n)
$ U' C* k) o& a/ w4 }2 \
{ //检查数组start后面n项数据里面有多少个1
* X e% B$ R6 B
int count = 0;
% h' e- x% v/ e5 M& Z1 a
for (int i = start; i < start + n; i++) if (lib[i] == 0) count++;
6 g* ]* q! u. H
return count;
( H) E0 x7 D2 I, N j$ S& ~2 o7 c: W9 k
}
6 u% O; o3 s" l
作者:
bingcheers
时间:
2010-6-28 12:53
回复
trytoday
的帖子
# U) L6 V1 D+ k4 A
( ~+ S3 x [5 q* J1 @* b
1 N8 P+ G6 H# c' c
牛牛, 牛牛, 牛牛
作者:
trytoday
时间:
2010-6-28 22:09
问题已经被另一位高人解决,请参阅:
* m- d1 }+ P) _' T$ Y) R; s
http://topic.csdn.net/u/20100626 ... d-0495bbbb15fc.html
作者:
角凳
时间:
2010-9-7 20:20
好像不是很有意义...
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5