这次用C#玩下C的题目——角谷猜想
(百科非VIP不能复制多行字,截图吧)
题目链接
https://wenku.baidu.com/view/9fe88540cf84b9d528ea7afe.html
思路========================================================================
既然是特例举证普遍,那么需要证明不存在反例,我这里玩下穷举法,注意下Long类型的最值就好;
试了下,单线程算的话资源利用率不高就开多线程了
分值域开线程,顺便查了下这个猜想。。。
资料说是小于7*10^11的所有的正整数都OK,但没说具体那些不OK,注释了一段是想拿来测试的就是没试出来,这段测试代码估计也是答案里的运算代码,但问题是怎么证明不OK呢,毕竟人家猜想的设定是只要不OK都要继续算。。。那么,数字是有限的,如果真的出不来,那么肯定是循环处理了相同数字导致出不来,所以步数可能超多;
那么这个相同的数、曾经处理过的数就是我们要找的;
因为我这里是一个分区占一个key值如果这个分区试完就会少一个key
谁想CUP内存发热发烫就玩下吧,如果把【Thread.Sleep(1)】放出来就不用发烫了。。。我这里烫了几分钟就不敢玩下去了。。。。
int quitLongCount = 0;
ConcurrentDictionary<string, long> testingLongDic = new ConcurrentDictionary<string, long>();
int maxStep = 0;// 最大步数
int part =100;// 分区数,一区一个线程处理
bool isFind = false;
for (long k = 0; k < part; k++)
{
long t = (long.MaxValue - 1) / 3 / part;
long part_k = k;
new Thread(() =>
{
for (long i = t * part_k + 7 * (long)Math.Pow(10, 11); i < t * (part_k + 1); i++)
{
long testLong = i;
long orgTestLong = testLong;
Dictionary<long,long> numbers = new Dictionary<long, long>();
testingLongDic.TryAdd(orgTestLong + "", part_k);// 处理的数字 , 线程号
int cycleTime_2 = 0;
int cycleTime_3 = 0;
while (true)
{
if (numbers.ContainsKey(testLong))
{
Console.WriteLine("targetLong:" + testLong);
isFind = true;
break;
}
else
{
numbers.Add(testLong, cycleTime_2 + cycleTime_3);
}
if (testLong % 2 == 0)
{
testLong /= 2;
++cycleTime_2;
//Console.WriteLine(testLong + ":" + cycleTime_2);
}
else
{
if (testLong > (long.MaxValue - 1) / 3)
{
quitLongCount++;
break;
}
testLong = testLong * 3 + 1;
++cycleTime_3;
//Console.WriteLine(testLong + ":" + cycleTime_3);
}
if (testLong == 1)
{
//Console.WriteLine(orgTestLong + "_2:" + cycleTime_2);
//Console.WriteLine(orgTestLong + "_3:" + cycleTime_3);
int cycleTime = cycleTime_2 + cycleTime_3;
maxStep = cycleTime > maxStep ? cycleTime : maxStep;
break;
}
//Thread.Sleep(1);// 无限循环不加容易抛异常
}
if (!isFind)
{
testingLongDic.TryRemove(orgTestLong + "", out long test);
}
else
{
break;
}
}
}).Start();
}
Console.ReadKey();