[**************] 唐 果 计算机软件与理论
美国大选50州1区(共51个)两派选票数可打平
---------269:269 会有很多种可能
各州的选票分布(总共538票):
(4) ---->缅因州
(7) ---->俄勒冈州 (10) ---->马里兰州 (21) ---->宾夕法尼亚州 (12) ---->马萨诸塞州 (4) ---->罗得岛州 (55) ---->加利福尼亚州 (17) ---->密歇根州 (9) ---->科罗拉多州 (10) ---->明尼苏达州 (7) ---->康涅狄格州 (3) ---->特拉华州 (3) ---->哥伦比亚特区 (27) ---->佛罗里达州 (3) ---->佛蒙特州 (5) ---->内华达州 (13) ---->弗吉尼亚州 (4) ---->夏威夷州 (11) ---->华盛顿州 (15) ---->新泽西州
(4) ---->新罕布什尔州
(21) ---->伊利诺伊州 (5) ---->新墨西哥州 (11) ---->印第安纳州 (31) ---->纽约州 (7) ---->艾奥瓦州 (20) ---->俄亥俄州
---->麦凯恩(21州) 163票 (9) ---->阿拉巴马州 (9) ---->路易斯安那州 (7) ---->俄克拉何马州 (3) ---->阿拉斯加州 (10) ---->亚利桑那州 (6) ---->阿肯色州 (8) ---->南卡罗来纳州 (10) ---->威斯康星州
U
nR
eg
is
te
re
d
(3) ---->南达科他州 (6) ---->密西西比州 (11) ---->田纳西州 (34) ---->得克萨斯州 (3) ---->蒙大拿州 (5) ---->犹他州 (5) ---->内布拉斯加州 (15) ---->佐治亚州 (4) ---->爱达荷州 (5) ---->西弗吉尼亚州 (3) ---->怀俄明州 (6) ---->堪萨斯州 (3) ---->北达科他州 (8) ---->肯塔基州
---->未决胜负州(2州) (11) ---->密苏里州 (15) ---->北卡罗来纳州
总的思路:
将51地方的选票数按降序排列后,从大到小依次相加,12个数就会超过269;因此随机选取数(不能重复)的个数可以是12到39,即(12,39);
然后将选取的随机数(不能重复)相加;看结果是否为269或者很靠近269;
由于51个数选14个的所有组合可达到千亿次,故随机选取的选票数之和为269可能很小,编程实现查看结果也很困难;
所以可选取一个数值范围,左右都比较靠近269,即比如【250到280】(当然范围数值也不固定,可自行设定),这样取随机数做循环的次数就很减少了,可根据实际设定。当找到选票之和介于250到280之间时,此时与269的差额与各州的选票数进行直接和间接(随机的各州选票之和等于差额)的匹配就完成。
具体思路:
1、 将51个地方的选票数存储到ArrayList或者数组中;
2、 产生随机种子,对ArrayList的下标进行随机选取(绝对不能重复);随机数为1—51; 3、 在编程的实验中,随机选取14个数,容易使随机的选票数之后更容易落在范围250到
280之间,而且更合理。将随机选取的14个数存到数组array中;
4、 利用递归函数getNumber()来检测生成的随机数(数组下标1---51)是否有重复,如果
取出来的数字和array数组中已取得的有重复就重新随机获取数;
5、 将随机数的数组下标按升序或降序排列,以方便查看是否取出的随机数有重复; 6、 对循环取出不重复的下标随机数所对应ArrayList中的数进行求和,看和是否在
250—280之间;如果选票数之后再250—280之间,循环终止,结束。
7、 此时选票数之和与269的差额与各州的选票数进行直接和间接(随机的各州选票之和
等于差额)的匹配就完成。
U
nR
eg
is
te
re
d
实际情况举例说明:
可以看出下图选票之和为262,与269相差7;故在ArrayList中可以很快很直接的找到票数为7的州或者几个州的选票数之和为7的结果;
票数为7的州:(7) ---->俄勒冈州;(7) ---->康涅狄格州; (7) ---->俄克拉何马州 几个州的选票数之和为7的州(3票+4票 组合):(4)---->缅因州 +(3) ---->特拉
华州;情况很多,就不再一一列举。
eg
is
U
nR
运行中其他的随机情况(267, 258,256, 255,254,253):
te
re
d
d
UnRegistere
附递归函数getNumber判断不重复:
public static int getNumber(int[] array, int randIndex, int stateNumber, Random rand) {
for (int j = 0; j
if (array[j] == randIndex)
{
randIndex = rand.Next(1,stateNumber); //如果有重复,重新获取随机数 getNumber(array, randIndex, stateNumber, rand); //递归调用。如果取出来的数字和已取得的数字有重复就重新随机获取。 } }
return randIndex; }
附 C#源代码: using System;
using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System.Numeric;
namespace USA2008Votion {
class Program {
和已取得的有重复就重新随机获取数。
{ {
public static int getNumber(int[] array, int randIndex, int stateNumber, Random rand) for (int j = 0; j
randIndex = rand.Next(1,stateNumber); //如果有重复,重新获取随机数 getNumber(array, randIndex, stateNumber, rand); //递归调用。如果取出来的数字和已取得的数字有重复就重新随机获取。 } }
return randIndex; }
static void Main(string[] args) {
ArrayList votionNum = new ArrayList();
votionNum.Add(-1); //程序后的递归调用函数中数组的默认值为0。为了避免取出的随机
U
nR
eg
is
//递归函数getNumber函数来检测生成的随机数(数组下标1---51)是否有重复,如果取出来的数字
te
re
d
数与0重复,故ArrayList从位置1开始存放选票数。
//奥巴马(27州1区)349票 votionNum.Add(4); //缅因州 votionNum.Add(7); //俄勒冈州 votionNum.Add(10); //马里兰州 votionNum.Add(21); //宾夕法尼亚州 votionNum.Add(12); //马萨诸塞州 votionNum.Add(4); //罗得岛州 votionNum.Add(55); //加利福尼亚州 votionNum.Add(17); //密歇根州 votionNum.Add(9); //科罗拉多州 votionNum.Add(10); //明尼苏达州 votionNum.Add(7); //康涅狄格州 votionNum.Add(3); //特拉华州 votionNum.Add(3); //哥伦比亚特区 votionNum.Add(27); //佛罗里达州 votionNum.Add(3); //佛蒙特州 votionNum.Add(5); //内华达州 votionNum.Add(13); //弗吉尼亚州 votionNum.Add(4); //夏威夷州 votionNum.Add(11); //华盛顿州 votionNum.Add(15); //新泽西州
votionNum.Add(21); //伊利诺伊州 votionNum.Add(5); //新墨西哥州 votionNum.Add(10); //威斯康星州 votionNum.Add(11); //印第安纳州 votionNum.Add(31); //纽约州 votionNum.Add(7); //艾奥瓦州
votionNum.Add(20); //俄亥俄州 //麦凯恩(21州) 163票
votionNum.Add(9); //阿拉巴马州
votionNum.Add(9); //路易斯安那州 votionNum.Add(7); //俄克拉何马州 votionNum.Add(3); //阿拉斯加州 votionNum.Add(10); //亚利桑那州 votionNum.Add(6); //阿肯色州 votionNum.Add(8); //南卡罗来纳州 votionNum.Add(3); //南达科他州 votionNum.Add(6); //密西西比州 votionNum.Add(11); //田纳西州 votionNum.Add(34); //得克萨斯州
U
nR
eg
is
votionNum.Add(4); //新罕布什尔州
te
re
d
votionNum.Add(3); //蒙大拿州 votionNum.Add(5); //犹他州 votionNum.Add(5); //内布拉斯加州 votionNum.Add(15); //佐治亚州 votionNum.Add(4); //爱达荷州 votionNum.Add(5); //西弗吉尼亚州 votionNum.Add(3); //怀俄明州 votionNum.Add(6); //堪萨斯州 votionNum.Add(3); //北达科他州 votionNum.Add(8); //肯塔基州
//未决胜负州(2州)
votionNum.Add(11); //密苏里州 votionNum.Add(15); //北卡罗来纳州
//50个州1个区--总共51个
int stateNumber = votionNum.Count;
Random rand = new Random(); long tick = DateTime.Now.Ticks;
int randIndex = -1;
{ 12个数就会超过269;
for (int m = 0; m
int[] array = new int[14]; /*将51地方的选票数按降序排列后,从大到小依次相加, *因此随机选取数的个数可以是12到39,即(12,39) */ for (int i = 0; i
randIndex = rand.Next(1,stateNumber); //获取随机数(1----51)
array[i] = getNumber(array, randIndex, stateNumber, rand); //将值赋到数组当中
}
//将随机数的数组下标按升序或降序排列,以方便查看是否取出的随机数有重复 for (int n1 = 0; n1
if ( array[n2]
U
nR
eg
is
Random ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
te
re
d
{
int temp = array[n1]; array[n1] = array[n2]; array[n2] = temp; } }
int total = 0;
for (int k = 0; k
System.Console.WriteLine("选票数的数组下标: "+array[k] + " " + "选票数: " + votionNum[array[k]]);
total = (int)votionNum[array[k]] + total; }
System.Console.WriteLine();
很小,编程实现查看结果也很困难 值也不固定)*/
System.Console.WriteLine("选票的总和: "+total);
/*由于51个数选14个的所有组合可达到千亿次,故随机选取的选票数之和为269可能 所以可选取一个数值范围,左右比较靠近269,即比如【250到280】(当然范围数
if (total>=250&&total
System.Console.WriteLine("-------------------------------"); }
System.Console.ReadLine(); } } }
U
System.Console.WriteLine();
nR
eg
is
te
re
d
[**************] 唐 果 计算机软件与理论
美国大选50州1区(共51个)两派选票数可打平
---------269:269 会有很多种可能
各州的选票分布(总共538票):
(4) ---->缅因州
(7) ---->俄勒冈州 (10) ---->马里兰州 (21) ---->宾夕法尼亚州 (12) ---->马萨诸塞州 (4) ---->罗得岛州 (55) ---->加利福尼亚州 (17) ---->密歇根州 (9) ---->科罗拉多州 (10) ---->明尼苏达州 (7) ---->康涅狄格州 (3) ---->特拉华州 (3) ---->哥伦比亚特区 (27) ---->佛罗里达州 (3) ---->佛蒙特州 (5) ---->内华达州 (13) ---->弗吉尼亚州 (4) ---->夏威夷州 (11) ---->华盛顿州 (15) ---->新泽西州
(4) ---->新罕布什尔州
(21) ---->伊利诺伊州 (5) ---->新墨西哥州 (11) ---->印第安纳州 (31) ---->纽约州 (7) ---->艾奥瓦州 (20) ---->俄亥俄州
---->麦凯恩(21州) 163票 (9) ---->阿拉巴马州 (9) ---->路易斯安那州 (7) ---->俄克拉何马州 (3) ---->阿拉斯加州 (10) ---->亚利桑那州 (6) ---->阿肯色州 (8) ---->南卡罗来纳州 (10) ---->威斯康星州
U
nR
eg
is
te
re
d
(3) ---->南达科他州 (6) ---->密西西比州 (11) ---->田纳西州 (34) ---->得克萨斯州 (3) ---->蒙大拿州 (5) ---->犹他州 (5) ---->内布拉斯加州 (15) ---->佐治亚州 (4) ---->爱达荷州 (5) ---->西弗吉尼亚州 (3) ---->怀俄明州 (6) ---->堪萨斯州 (3) ---->北达科他州 (8) ---->肯塔基州
---->未决胜负州(2州) (11) ---->密苏里州 (15) ---->北卡罗来纳州
总的思路:
将51地方的选票数按降序排列后,从大到小依次相加,12个数就会超过269;因此随机选取数(不能重复)的个数可以是12到39,即(12,39);
然后将选取的随机数(不能重复)相加;看结果是否为269或者很靠近269;
由于51个数选14个的所有组合可达到千亿次,故随机选取的选票数之和为269可能很小,编程实现查看结果也很困难;
所以可选取一个数值范围,左右都比较靠近269,即比如【250到280】(当然范围数值也不固定,可自行设定),这样取随机数做循环的次数就很减少了,可根据实际设定。当找到选票之和介于250到280之间时,此时与269的差额与各州的选票数进行直接和间接(随机的各州选票之和等于差额)的匹配就完成。
具体思路:
1、 将51个地方的选票数存储到ArrayList或者数组中;
2、 产生随机种子,对ArrayList的下标进行随机选取(绝对不能重复);随机数为1—51; 3、 在编程的实验中,随机选取14个数,容易使随机的选票数之后更容易落在范围250到
280之间,而且更合理。将随机选取的14个数存到数组array中;
4、 利用递归函数getNumber()来检测生成的随机数(数组下标1---51)是否有重复,如果
取出来的数字和array数组中已取得的有重复就重新随机获取数;
5、 将随机数的数组下标按升序或降序排列,以方便查看是否取出的随机数有重复; 6、 对循环取出不重复的下标随机数所对应ArrayList中的数进行求和,看和是否在
250—280之间;如果选票数之后再250—280之间,循环终止,结束。
7、 此时选票数之和与269的差额与各州的选票数进行直接和间接(随机的各州选票之和
等于差额)的匹配就完成。
U
nR
eg
is
te
re
d
实际情况举例说明:
可以看出下图选票之和为262,与269相差7;故在ArrayList中可以很快很直接的找到票数为7的州或者几个州的选票数之和为7的结果;
票数为7的州:(7) ---->俄勒冈州;(7) ---->康涅狄格州; (7) ---->俄克拉何马州 几个州的选票数之和为7的州(3票+4票 组合):(4)---->缅因州 +(3) ---->特拉
华州;情况很多,就不再一一列举。
eg
is
U
nR
运行中其他的随机情况(267, 258,256, 255,254,253):
te
re
d
d
UnRegistere
附递归函数getNumber判断不重复:
public static int getNumber(int[] array, int randIndex, int stateNumber, Random rand) {
for (int j = 0; j
if (array[j] == randIndex)
{
randIndex = rand.Next(1,stateNumber); //如果有重复,重新获取随机数 getNumber(array, randIndex, stateNumber, rand); //递归调用。如果取出来的数字和已取得的数字有重复就重新随机获取。 } }
return randIndex; }
附 C#源代码: using System;
using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System.Numeric;
namespace USA2008Votion {
class Program {
和已取得的有重复就重新随机获取数。
{ {
public static int getNumber(int[] array, int randIndex, int stateNumber, Random rand) for (int j = 0; j
randIndex = rand.Next(1,stateNumber); //如果有重复,重新获取随机数 getNumber(array, randIndex, stateNumber, rand); //递归调用。如果取出来的数字和已取得的数字有重复就重新随机获取。 } }
return randIndex; }
static void Main(string[] args) {
ArrayList votionNum = new ArrayList();
votionNum.Add(-1); //程序后的递归调用函数中数组的默认值为0。为了避免取出的随机
U
nR
eg
is
//递归函数getNumber函数来检测生成的随机数(数组下标1---51)是否有重复,如果取出来的数字
te
re
d
数与0重复,故ArrayList从位置1开始存放选票数。
//奥巴马(27州1区)349票 votionNum.Add(4); //缅因州 votionNum.Add(7); //俄勒冈州 votionNum.Add(10); //马里兰州 votionNum.Add(21); //宾夕法尼亚州 votionNum.Add(12); //马萨诸塞州 votionNum.Add(4); //罗得岛州 votionNum.Add(55); //加利福尼亚州 votionNum.Add(17); //密歇根州 votionNum.Add(9); //科罗拉多州 votionNum.Add(10); //明尼苏达州 votionNum.Add(7); //康涅狄格州 votionNum.Add(3); //特拉华州 votionNum.Add(3); //哥伦比亚特区 votionNum.Add(27); //佛罗里达州 votionNum.Add(3); //佛蒙特州 votionNum.Add(5); //内华达州 votionNum.Add(13); //弗吉尼亚州 votionNum.Add(4); //夏威夷州 votionNum.Add(11); //华盛顿州 votionNum.Add(15); //新泽西州
votionNum.Add(21); //伊利诺伊州 votionNum.Add(5); //新墨西哥州 votionNum.Add(10); //威斯康星州 votionNum.Add(11); //印第安纳州 votionNum.Add(31); //纽约州 votionNum.Add(7); //艾奥瓦州
votionNum.Add(20); //俄亥俄州 //麦凯恩(21州) 163票
votionNum.Add(9); //阿拉巴马州
votionNum.Add(9); //路易斯安那州 votionNum.Add(7); //俄克拉何马州 votionNum.Add(3); //阿拉斯加州 votionNum.Add(10); //亚利桑那州 votionNum.Add(6); //阿肯色州 votionNum.Add(8); //南卡罗来纳州 votionNum.Add(3); //南达科他州 votionNum.Add(6); //密西西比州 votionNum.Add(11); //田纳西州 votionNum.Add(34); //得克萨斯州
U
nR
eg
is
votionNum.Add(4); //新罕布什尔州
te
re
d
votionNum.Add(3); //蒙大拿州 votionNum.Add(5); //犹他州 votionNum.Add(5); //内布拉斯加州 votionNum.Add(15); //佐治亚州 votionNum.Add(4); //爱达荷州 votionNum.Add(5); //西弗吉尼亚州 votionNum.Add(3); //怀俄明州 votionNum.Add(6); //堪萨斯州 votionNum.Add(3); //北达科他州 votionNum.Add(8); //肯塔基州
//未决胜负州(2州)
votionNum.Add(11); //密苏里州 votionNum.Add(15); //北卡罗来纳州
//50个州1个区--总共51个
int stateNumber = votionNum.Count;
Random rand = new Random(); long tick = DateTime.Now.Ticks;
int randIndex = -1;
{ 12个数就会超过269;
for (int m = 0; m
int[] array = new int[14]; /*将51地方的选票数按降序排列后,从大到小依次相加, *因此随机选取数的个数可以是12到39,即(12,39) */ for (int i = 0; i
randIndex = rand.Next(1,stateNumber); //获取随机数(1----51)
array[i] = getNumber(array, randIndex, stateNumber, rand); //将值赋到数组当中
}
//将随机数的数组下标按升序或降序排列,以方便查看是否取出的随机数有重复 for (int n1 = 0; n1
if ( array[n2]
U
nR
eg
is
Random ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
te
re
d
{
int temp = array[n1]; array[n1] = array[n2]; array[n2] = temp; } }
int total = 0;
for (int k = 0; k
System.Console.WriteLine("选票数的数组下标: "+array[k] + " " + "选票数: " + votionNum[array[k]]);
total = (int)votionNum[array[k]] + total; }
System.Console.WriteLine();
很小,编程实现查看结果也很困难 值也不固定)*/
System.Console.WriteLine("选票的总和: "+total);
/*由于51个数选14个的所有组合可达到千亿次,故随机选取的选票数之和为269可能 所以可选取一个数值范围,左右比较靠近269,即比如【250到280】(当然范围数
if (total>=250&&total
System.Console.WriteLine("-------------------------------"); }
System.Console.ReadLine(); } } }
U
System.Console.WriteLine();
nR
eg
is
te
re
d