答案是3和8 推理过程: 既然甲一开始说不知道,说明至少有两种可能,满足这样条件的乘积只可能是3个: 12, 18, 24 先看12,可能是2 X 6,也可能是 3 X 4.若 2 X 6,则乙得 8,对于乙来说,只有两种可能: 2 + 6 =8, 3 + 5 = 8,但3 X 5 = 15, 15对于甲来说只有一种可能,但甲说不知道,所以只可能是2和6,但乙却说不知道,可见不是12. 再看24,可能是4 X 6,也可能是3 X 8.若4和6,则乙得10,有两种可能: 4 + 6 = 10, 2 + 8 = 10, 对乙来说,2和8不可能,因为2 X 8 = 16只有一种可能。 若是3 X 8,则乙得11,两种可能: 2 + 9 = 11,3 + 8 = 11。 2 X 9 = 18对甲来说也有两种可能。所以乙一开始说不知道,而甲一听乙说不知道,就排除了4 X 6,故得3,8, 而乙也排除了2 + 9,同样得3,8。如何编程,容老夫再想想
好像上面说错了。怎么这个问题感觉无解? 首先,楼上说的3和4肯定是错的: 这时乙得7, 则 2 + 5, 3 + 4,但2 x 5只有一种可能,所以乙一开始就能推出是3和4。但乙说不知道,故矛盾。现在假设乙得了11,则2 + 9, 3 + 8,其他如4 + 7, 5 + 6对甲来说都只有一种可能,可排除。 2 + 9,甲得18,则 2 x 9, 3 x 6,甲推理:若3 x 6, 则乙得 9, 3 + 6, 2 + 7, 2 + 7一种可能,所以乙可推得3和6,但乙说不知道,则2和9。但是问题在于,当甲说知道了之后,乙不好推理,仍然无法知道是2和9还是3和8。因为若3和8,甲得24,3 x 8, 4 x 6,甲推理:若4 x 6,乙得10, 2 + 8(对甲来说16,一种可能),3 + 7(对甲来说21),4 + 6,所以乙可推得必为4 + 6,但乙说不知道,所以只能是3和8,乙得11,无法确定。也就是说,当甲回答说知道后,乙仍然无法确定是2和9还是3和8!所以乙怎么可能说知道呢?如果谁能证明我说错了,不胜感激!
VFP代码: Create Cursor tt (ti n(1),tj n(1),ixj n(2),ipj n(2)) For i= 2 To 9 For j=2 To 9 If i=j Loop Endif locate for ti=j And tj=i If Found() Loop Endif Insert Into tt Values (i,j,i*j,i+j) Endfor EndforSelect ixj,Count(ixj) as xn From tt Into Cursor t1 Group By ixj Having xn=1 Select t1 Scan Select tt Delete For ixj=t1.ixj Select t1 EndscanSelect ipj,Count(ipj) as xn From tt Into Cursor t1 Group By ipj Having xn=1 Select t1 Scan Select tt Delete For ipj=t1.ipj Select t1 Endscan Use In t1 Select tt Browse 结果有两条记录2/9,3/8,命题为假。9楼正确
写个程序算一下:using System; using System.Linq;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var 老师可能出的题 = from a in Enumerable.Range(2, 8) from b in Enumerable.Range(2, 8) where a < b select new { A = a, B = b, 积 = a * b, 和 = a + b }; var 甲说不知道时 = from u in 老师可能出的题 group u by u.积 into g where g.Count() > 1 select g.First(); var 乙说不知道时 = from u in 老师可能出的题 group u by u.和 into g where g.Count() > 1 select g.First(); var 甲说知道了时 = from u in 甲说不知道时 join v in 乙说不知道时 on u.积 equals v.积 group u by u.积 into g where g.Count() == 1 select g.First(); var 乙说知道了时 = from u in 乙说不知道时 join v in 甲说知道了时 on u.和 equals v.和 group u by u.和 into g where g.Count() == 1 select g.First(); foreach (var result in 乙说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); Console.ReadKey(); } } }
呵呵,修改一下using System; using System.Linq;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var 老师可能出的题 = from a in Enumerable.Range(2, 8) from b in Enumerable.Range(2, 8) where a < b select new { A = a, B = b, 积 = a * b, 和 = a + b }; var 甲说不知道时 = from u in 老师可能出的题 group u by u.积 into g where g.Count() > 1 select g.First(); var 乙说不知道时 = from u in 甲说不知道时 group u by u.和 into g where g.Count() > 1 select g.First(); var 甲说知道了时 = from u in 甲说不知道时 join v in 乙说不知道时 on u.积 equals v.积 group u by u.积 into g where g.Count() == 1 select g.First(); var 乙说知道了时 = from u in 乙说不知道时 join v in 甲说知道了时 on u.和 equals v.和 group u by u.和 into g where g.Count() == 1 select g.First(); foreach (var result in 乙说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); Console.ReadKey(); } } } 看看,修改了哪里?
那么再改一下好了!using System; using System.Linq;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var 老师可能出的题 = from a in Enumerable.Range(2, 8) from b in Enumerable.Range(2, 8) where a < b select new { A = a, B = b, 积 = a * b, 和 = a + b }; var 甲说不知道时 = from u in 老师可能出的题 group u by u.积 into g where g.Count() > 1 select g.First(); var 乙说不知道时 = from u in 甲说不知道时 group u by u.和 into g where g.Count() > 1 select g.First(); var 甲说知道了时 = from u in 乙说不知道时 group u by u.积 into g where g.Count() == 1 select g.First(); var 乙说知道了时 = from u in 甲说知道了时 group u by u.和 into g where g.Count() == 1 select g.First(); foreach (var result in 乙说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); Console.ReadKey(); } } }
嗯,还可以修改一行 from b in Enumerable.Range(a + 1, 9 - a) 不改了! 实际上这不是什么专门设计的算法,这是笨拙的遍历。只不过,Linq具有迭代器功能(linq的所谓“延迟计算”能力就是基于迭代器机制的),因此我们可以写出看似笨拙的遍历方法,然后让Linq编译器去给我们转换成为比较高效的迭代计算过程。在迭代过程中Linq所占用的内存很小,这是其优势。
牛~~~DDDDD 命题都没看明白的人伤不起啊~~~
有点问题啊,这个算法 var 甲说不知道时 = from u in 老师可能出的题 group u by u.积 into g where g.Count() > 1 select g.First(); 见上面这里按照 积 进行了一下group by操作, where条件 中 g.Count() > 1 所以 按照积分组了一下 针对相同积 情况下 只检索了 一个记录 丢失部分数据 可见结果不会正确的 针对积相同的数据
此推理正解 sp1234的程序明显BUG
不懂这句是什么意思。你可以在这句之后打印一下foreach (var result in 甲说不知道时) Console.WriteLine("A={0}, B={1}", result.A, result.B); 看看跟你想的结果是否一致!
恩,确实 g.First是有BUG的。我后边修改一下!
var 甲说不知道时 =from u in 老师可能出的题 group u by u.积 into g where g.Count() > 1 select g.First(); foreach (var result in 甲说不知道时) Console.WriteLine("A={0}, B={1},A*B={2}", result.A, result.B, result.积);结果如下: A=2, B=6,A*B=12 A=2, B=9,A*B=18 A=3, B=8,A*B=24 明显漏掉了 A=3, B=4, A*B=12 ... ... A=4, B=6, A*B=24 等类似情况 很抱歉上面没有说明白,举例你能明白吧... ...
恩,前边两个的g.First删除了,在增加代码打印了一下过程。using System; using System.Linq;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var 老师可能出的题 = from a in Enumerable.Range(2, 8) from b in Enumerable.Range(a + 1, 9 - a) where a < b select new { A = a, B = b, 积 = a * b, 和 = a + b }; var 甲说不知道时 = from u in 老师可能出的题 where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积) select u; Console.WriteLine("----------甲说不知道时"); foreach (var result in 甲说不知道时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 乙说不知道时 = from u in 甲说不知道时 where 甲说不知道时.Any(x => x.A != u.A && x.和 == u.和) select u; Console.WriteLine("----------乙说不知道时"); foreach (var result in 乙说不知道时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 甲说知道了时 = from u in 乙说不知道时 group u by u.积 into g where g.Count() == 1 select g.First(); Console.WriteLine("----------甲说知道了时"); foreach (var result in 甲说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 乙说知道了时 = from u in 甲说知道了时 group u by u.和 into g where g.Count() == 1 select g.First(); Console.WriteLine("----------乙说知道了时"); foreach (var result in 乙说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); Console.ReadKey(); } } }
其实假设“老师从1到9中取两个数字”,这个题目就有解了。using System; using System.Linq;namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var 老师可能出的题 = from a in Enumerable.Range(1, 9) from b in Enumerable.Range(a + 1, 9 - a) select new { A = a, B = b, 积 = a * b, 和 = a + b }; var 甲说不知道时 = from u in 老师可能出的题 where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积) select u; Console.WriteLine("----------甲说不知道时"); foreach (var result in 甲说不知道时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 乙说不知道时 = from u in 甲说不知道时 where 甲说不知道时.Any(x => x.A != u.A && x.和 == u.和) select u; Console.WriteLine("----------乙说不知道时"); foreach (var result in 乙说不知道时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 甲说知道了时 = from u in 乙说不知道时 group u by u.积 into g where g.Count() == 1 select g.First(); Console.WriteLine("----------甲说知道了时"); foreach (var result in 甲说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); var 乙说知道了时 = from u in 甲说知道了时 group u by u.和 into g where g.Count() == 1 select g.First(); Console.WriteLine("----------乙说知道了时"); foreach (var result in 乙说知道了时) Console.WriteLine("A={0}, B={1}", result.A, result.B); Console.ReadKey(); } } }
告诉一个积,,,就只有3组方案的案中的一个 2*9=18 3*62*6=12 3*43*8=24 4*6答案应该只有一个..当然要先知道 积 and 和 呀~~~~~~~~~~~~~~~~~~~~~ 18 and 11 =2/9 18 and 9 =3/612 and 8 =2/6 12 and 7 =3/424 and 11 =3/8 (注:这组中和11和组一重复了....^_^) 24 and 10 =4/6甲知道积说不知道数字,已听了之后就会去分析答案.他会做很多假设..如果积是18 or 12 or 24以上只有一种情况已才是不知道...那就是和为11时.事实的确是11,两个答案而已不确认是哪个只能说我也不知道,而甲听了已说不知道后,就知道已的和是11,因为甲知道积,所以他知道答案了, 如果积是18.他的答案就是2/9.如果积是24答案就是3/8而题目中最后[已又说我知道],其实应该是错的,,已还是不知道 假设积是18 和是 11 ,已知道了,那答案是哪个,他不知道积,18,24都是满足条件
推理过程:
既然甲一开始说不知道,说明至少有两种可能,满足这样条件的乘积只可能是3个:
12, 18, 24
先看12,可能是2 X 6,也可能是 3 X 4.若 2 X 6,则乙得 8,对于乙来说,只有两种可能: 2 + 6 =8, 3 + 5 = 8,但3 X 5 = 15, 15对于甲来说只有一种可能,但甲说不知道,所以只可能是2和6,但乙却说不知道,可见不是12.
再看24,可能是4 X 6,也可能是3 X 8.若4和6,则乙得10,有两种可能: 4 + 6 = 10, 2 + 8 = 10, 对乙来说,2和8不可能,因为2 X 8 = 16只有一种可能。
若是3 X 8,则乙得11,两种可能: 2 + 9 = 11,3 + 8 = 11。 2 X 9 = 18对甲来说也有两种可能。所以乙一开始说不知道,而甲一听乙说不知道,就排除了4 X 6,故得3,8, 而乙也排除了2 + 9,同样得3,8。如何编程,容老夫再想想
首先,楼上说的3和4肯定是错的:
这时乙得7, 则 2 + 5, 3 + 4,但2 x 5只有一种可能,所以乙一开始就能推出是3和4。但乙说不知道,故矛盾。现在假设乙得了11,则2 + 9, 3 + 8,其他如4 + 7, 5 + 6对甲来说都只有一种可能,可排除。
2 + 9,甲得18,则 2 x 9, 3 x 6,甲推理:若3 x 6, 则乙得 9, 3 + 6, 2 + 7, 2 + 7一种可能,所以乙可推得3和6,但乙说不知道,则2和9。但是问题在于,当甲说知道了之后,乙不好推理,仍然无法知道是2和9还是3和8。因为若3和8,甲得24,3 x 8, 4 x 6,甲推理:若4 x 6,乙得10, 2 + 8(对甲来说16,一种可能),3 + 7(对甲来说21),4 + 6,所以乙可推得必为4 + 6,但乙说不知道,所以只能是3和8,乙得11,无法确定。也就是说,当甲回答说知道后,乙仍然无法确定是2和9还是3和8!所以乙怎么可能说知道呢?如果谁能证明我说错了,不胜感激!
Create Cursor tt (ti n(1),tj n(1),ixj n(2),ipj n(2))
For i= 2 To 9
For j=2 To 9
If i=j
Loop
Endif
locate for ti=j And tj=i
If Found()
Loop
Endif
Insert Into tt Values (i,j,i*j,i+j)
Endfor
EndforSelect ixj,Count(ixj) as xn From tt Into Cursor t1 Group By ixj Having xn=1
Select t1
Scan
Select tt
Delete For ixj=t1.ixj
Select t1
EndscanSelect ipj,Count(ipj) as xn From tt Into Cursor t1 Group By ipj Having xn=1
Select t1
Scan
Select tt
Delete For ipj=t1.ipj
Select t1
Endscan
Use In t1
Select tt
Browse 结果有两条记录2/9,3/8,命题为假。9楼正确
using System.Linq;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var 老师可能出的题 = from a in Enumerable.Range(2, 8)
from b in Enumerable.Range(2, 8)
where a < b
select new { A = a, B = b, 积 = a * b, 和 = a + b };
var 甲说不知道时 = from u in 老师可能出的题
group u by u.积 into g
where g.Count() > 1
select g.First();
var 乙说不知道时 = from u in 老师可能出的题
group u by u.和 into g
where g.Count() > 1
select g.First();
var 甲说知道了时 = from u in 甲说不知道时
join v in 乙说不知道时 on u.积 equals v.积
group u by u.积 into g
where g.Count() == 1
select g.First();
var 乙说知道了时 = from u in 乙说不知道时
join v in 甲说知道了时 on u.和 equals v.和
group u by u.和 into g
where g.Count() == 1
select g.First();
foreach (var result in 乙说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
Console.ReadKey();
}
}
}
using System.Linq;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var 老师可能出的题 = from a in Enumerable.Range(2, 8)
from b in Enumerable.Range(2, 8)
where a < b
select new { A = a, B = b, 积 = a * b, 和 = a + b };
var 甲说不知道时 = from u in 老师可能出的题
group u by u.积 into g
where g.Count() > 1
select g.First();
var 乙说不知道时 = from u in 甲说不知道时
group u by u.和 into g
where g.Count() > 1
select g.First();
var 甲说知道了时 = from u in 甲说不知道时
join v in 乙说不知道时 on u.积 equals v.积
group u by u.积 into g
where g.Count() == 1
select g.First();
var 乙说知道了时 = from u in 乙说不知道时
join v in 甲说知道了时 on u.和 equals v.和
group u by u.和 into g
where g.Count() == 1
select g.First();
foreach (var result in 乙说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
Console.ReadKey();
}
}
}
看看,修改了哪里?
using System.Linq;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var 老师可能出的题 = from a in Enumerable.Range(2, 8)
from b in Enumerable.Range(2, 8)
where a < b
select new { A = a, B = b, 积 = a * b, 和 = a + b };
var 甲说不知道时 = from u in 老师可能出的题
group u by u.积 into g
where g.Count() > 1
select g.First();
var 乙说不知道时 = from u in 甲说不知道时
group u by u.和 into g
where g.Count() > 1
select g.First();
var 甲说知道了时 = from u in 乙说不知道时
group u by u.积 into g
where g.Count() == 1
select g.First();
var 乙说知道了时 = from u in 甲说知道了时
group u by u.和 into g
where g.Count() == 1
select g.First();
foreach (var result in 乙说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
Console.ReadKey();
}
}
}
不改了!
实际上这不是什么专门设计的算法,这是笨拙的遍历。只不过,Linq具有迭代器功能(linq的所谓“延迟计算”能力就是基于迭代器机制的),因此我们可以写出看似笨拙的遍历方法,然后让Linq编译器去给我们转换成为比较高效的迭代计算过程。在迭代过程中Linq所占用的内存很小,这是其优势。
牛~~~DDDDD 命题都没看明白的人伤不起啊~~~
var 甲说不知道时 = from u in 老师可能出的题
group u by u.积 into g
where g.Count() > 1
select g.First();
见上面这里按照 积 进行了一下group by操作, where条件 中 g.Count() > 1
所以 按照积分组了一下 针对相同积 情况下 只检索了 一个记录 丢失部分数据
可见结果不会正确的
针对积相同的数据
sp1234的程序明显BUG
不懂这句是什么意思。你可以在这句之后打印一下foreach (var result in 甲说不知道时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
看看跟你想的结果是否一致!
恩,确实 g.First是有BUG的。我后边修改一下!
group u by u.积 into g
where g.Count() > 1
select g.First(); foreach (var result in 甲说不知道时)
Console.WriteLine("A={0}, B={1},A*B={2}", result.A, result.B, result.积);结果如下:
A=2, B=6,A*B=12
A=2, B=9,A*B=18
A=3, B=8,A*B=24
明显漏掉了 A=3, B=4, A*B=12
... ...
A=4, B=6, A*B=24 等类似情况
很抱歉上面没有说明白,举例你能明白吧... ...
和有重复的&&积有重复的&&重复的和的个数是2&&重复的积的个数也是2
满足这个条件的只有2,6和3,4这两组数
using System.Linq;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var 老师可能出的题 = from a in Enumerable.Range(2, 8)
from b in Enumerable.Range(a + 1, 9 - a)
where a < b
select new { A = a, B = b, 积 = a * b, 和 = a + b };
var 甲说不知道时 = from u in 老师可能出的题
where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积)
select u;
Console.WriteLine("----------甲说不知道时");
foreach (var result in 甲说不知道时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 乙说不知道时 = from u in 甲说不知道时
where 甲说不知道时.Any(x => x.A != u.A && x.和 == u.和)
select u;
Console.WriteLine("----------乙说不知道时");
foreach (var result in 乙说不知道时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 甲说知道了时 = from u in 乙说不知道时
group u by u.积 into g
where g.Count() == 1
select g.First();
Console.WriteLine("----------甲说知道了时");
foreach (var result in 甲说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 乙说知道了时 = from u in 甲说知道了时
group u by u.和 into g
where g.Count() == 1
select g.First();
Console.WriteLine("----------乙说知道了时");
foreach (var result in 乙说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
Console.ReadKey();
}
}
}
using System.Linq;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var 老师可能出的题 = from a in Enumerable.Range(1, 9)
from b in Enumerable.Range(a + 1, 9 - a)
select new { A = a, B = b, 积 = a * b, 和 = a + b };
var 甲说不知道时 = from u in 老师可能出的题
where 老师可能出的题.Any(x => x.A != u.A && x.积 == u.积)
select u;
Console.WriteLine("----------甲说不知道时");
foreach (var result in 甲说不知道时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 乙说不知道时 = from u in 甲说不知道时
where 甲说不知道时.Any(x => x.A != u.A && x.和 == u.和)
select u;
Console.WriteLine("----------乙说不知道时");
foreach (var result in 乙说不知道时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 甲说知道了时 = from u in 乙说不知道时
group u by u.积 into g
where g.Count() == 1
select g.First();
Console.WriteLine("----------甲说知道了时");
foreach (var result in 甲说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
var 乙说知道了时 = from u in 甲说知道了时
group u by u.和 into g
where g.Count() == 1
select g.First();
Console.WriteLine("----------乙说知道了时");
foreach (var result in 乙说知道了时)
Console.WriteLine("A={0}, B={1}", result.A, result.B);
Console.ReadKey();
}
}
}
2*9=18
3*62*6=12
3*43*8=24
4*6答案应该只有一个..当然要先知道 积 and 和 呀~~~~~~~~~~~~~~~~~~~~~
18 and 11 =2/9
18 and 9 =3/612 and 8 =2/6
12 and 7 =3/424 and 11 =3/8 (注:这组中和11和组一重复了....^_^)
24 and 10 =4/6甲知道积说不知道数字,已听了之后就会去分析答案.他会做很多假设..如果积是18 or 12 or 24以上只有一种情况已才是不知道...那就是和为11时.事实的确是11,两个答案而已不确认是哪个只能说我也不知道,而甲听了已说不知道后,就知道已的和是11,因为甲知道积,所以他知道答案了,
如果积是18.他的答案就是2/9.如果积是24答案就是3/8而题目中最后[已又说我知道],其实应该是错的,,已还是不知道
假设积是18 和是 11 ,已知道了,那答案是哪个,他不知道积,18,24都是满足条件