2018刑侦推理题算法
in C#Algorithm with 2 comments
Read:324

2018刑侦推理题算法

in C#Algorithm with 2 comments

2018tuili.jpg

就是这个,咋的一看,卧槽什么鬼。仔细想一想就会发现,根本不需要自己动脑子,给cpu限定条件让它算。用的语言是C#。穷举法,还是可以的,举了了8w多次就举出来了,最大穷举值4的10次方是1048576。


首先我们创建一个数组用来保存十道题的答案

//十道题的答案,0,1,2,3代表A,B,C,D
int[] answer = new int[10];

这时候我们就要知道每道题怎么个算

第一题

//第一题:这道题的答案是?这道题的答案无关紧要都可以
bool T1()
{
    return true;
}

第二题

//第二题:第五题的答案是?a.C b.D c.A d.B
bool T2()
{
    int T5=-1;
    switch (answer[1])
    {
        case 0:T5 = 2;break;//当第二题选A,那么第五题就是C
        case 1:T5 = 3;break;//当第二题选B,那么第五题就是D
        case 2:T5 = 0;break;//当第二题选C,那么第五题就是A
        case 3:T5 = 1;break;//当第二题选D,那么第五题就是B
    }
    if (T5 == answer[4])//如果答案对上了,就返回True
        return true;
    else
        return false;
}

第三题

 //第三题:以下选项中哪一题的答案与其他三项不同:a.第三题 b.第六题 c.第二题 d.第四题
        bool T3()
        {
            switch (answer[2])
            {
                case 0:
                    //如果第三题选择A,那么也就是意味着第624题一样,第3题和624不一样
                    if (answer[5] == answer[1] && answer[1] == answer[3])
                    {
                        if (answer[2] != answer[5])
                            return true;
                    }break;
                case 1:
                    //如果第三题选择B,那么也就是意味着第324题一样,第6题和324不一样
                    if (answer[2] == answer[1] && answer[1] == answer[3])
                    {
                        if (answer[5] != answer[2])
                            return true;
                    }break;
                case 2:
                    //如果第三题选择C,那么也就是意味着第364题一样,第2题和364不一样
                    if (answer[2] == answer[5] && answer[5] == answer[3])
                    {
                        if (answer[1] != answer[2])
                            return true;
                    }break;
                case 3:
                    //如果第三题选择D,那么也就是意味着第362题一样,第4题和362不一样
                    if (answer[2]==answer[5]&&answer[5]==answer[1])
                    {
                        if (answer[3] != answer[2])
                            return true;
                    }break;
            }
            return false;
        }

第四题

//第四题:以下选项中哪两题的答案相同:a.第1,5题 b.第2,7题 c.第1,9题 d.第6,10题
bool T4()
{
    switch (answer[3])
    {
        case 0:
            if (answer[0] == answer[4])
                return true;
            break;
        case 1:
            if (answer[1] == answer[6])
                return true;
            break;
        case 2:
            if (answer[0] == answer[8])
                return true;
            break;
        case 3:
            if (answer[5] == answer[9])
                return true;
            break;
    }
    return false;
}

第五题

//第五题:以下选项中哪一题的答案与本题相同:a.第8题 b.第4题 c.第9题 d.第7题
bool T5()
{
    switch(answer[4])
    {
        case 0:
            if (answer[4] == answer[7])
                return true;
            break;
        case 1:
            if (answer[4] == answer[3])
                return true;
            break;
        case 2:
            if (answer[4] == answer[8])
                return true;
            break;
        case 3:
            if (answer[4] == answer[6])
                return true;
            break;
    }
    return false;
}

第六题

//第六题:一下选项中哪两项的答案与第八题相同:a.第2,4题 b.第1,6题 c.第3,10题 d.第5,9题
bool T6()
{
    switch(answer[5])
    {
        case 0:
            if (answer[7] == answer[1] && answer[7] == answer[3])
                return true;
            break;
        case 1:
            if (answer[7] == answer[0] && answer[7] == answer[5])
                return true;
            break;
        case 2:
            if (answer[7] == answer[2] && answer[7] == answer[9])
                return true;
            break;
        case 3:
            if (answer[7] == answer[4] && answer[7] == answer[8])
                return true;
            break;
    }
    return false;
}

第七题

//第七题:在此十题中,被选中次数最少的选项字母为:a.C b.B c.A d.D
bool T7()
{
    //声明一个字典泛型,键是选项,值是次数
    Dictionary<int, int> dic = new Dictionary<int, int>();
    foreach (int i in answer)//遍历答案数组,得到的i,无非就是0,1,2,3
    {
        //判断键是否存在,不存在就添加一个键,值为0
        if (!dic.ContainsKey(i))
            dic.Add(i, 0);
        dic[i]++;//统计次数
    }
    //得出一个最小的值
    int min = 4;
    foreach (int i in dic.Values)
    {
        if (min >i)
            min = i;
    }
    switch(answer[6])
    {
        case 0:
            if (dic[2] == min)
                return true;
            break;
        case 1:
            if (dic[1] == min)
                return true;
            break;
        case 2:
            if (dic[0] == min)
                return true;
            break;
        case 3:
            if (dic[3] == min)
                return true;
            break;
    }
    return false;

}

第八题

//第八题:以下选项中哪一题的答案与第一题的答案在字母中的位子不相邻:a.第7题 b.第5题 c.第2题 d.第10题
bool T8()
{
    switch(answer[7])
    {
        case 0:
            //数学函数Abs函数计算绝对值,如果两个选项的差的绝对值大于1就是不相邻
            if (Math.Abs(answer[0] - answer[6]) > 1)
                return true;
            break;
        case 1:
            if (Math.Abs(answer[0] - answer[4]) > 1)
                return true;
            break;
        case 2:
            if (Math.Abs(answer[0] - answer[1]) > 1)
                return true;
            break;
        case 3:
            if (Math.Abs(answer[0] - answer[9]) > 1)
                return true;
            break;
    }
    return false;
}

第九题

//第九题:已知“第一题与第六题的答案相同”与“第X题与第5题的答案相同”的真假性相反那么X为:
//a.第6题 b.第10题 c.第2题 d.第9题
bool T9()
{
    switch (answer[8])
    {
        case 0:
            if (answer[0] != answer[5] && answer[5] == answer[4])
                return true;
            if (answer[0] == answer[5] && answer[5] != answer[4])
                return true;
            break;
        case 1:
            if (answer[0] != answer[5] && answer[9] == answer[4])
                return true;
            if (answer[0] == answer[5] && answer[9] != answer[4])
                return true;
            break;
        case 2:
            if (answer[0] != answer[5] && answer[1] == answer[4])
                return true;
            if (answer[0] == answer[5] && answer[1] != answer[4])
                return true;
            break;
        case 3:
            if (answer[0] != answer[5] && answer[8] == answer[4])
                return true;
            if (answer[0] == answer[5] && answer[8] != answer[4])
                return true;
            break;
    }
    return false;
}

第十题

//第十题:在十道题中ABCD四个字母出现次数最多与最少者的差为:a.3 b.2 c.4 .1
bool T10()
{
    //与第7题原理差不多
    Dictionary<int, int> dic = new Dictionary<int, int>();
    foreach (int i in answer)
    {
        if (!dic.ContainsKey(i))
            dic.Add(i, 0);
        dic[i]++;
    }
    //得出一个最小最大的值
    int min = 4;
    int max = -1;
    foreach (int i in dic.Values)
    {
        if (min > i)
            min = i;
        if (max < i)
            max = i;
    }
    switch (answer[9])
    {
        case 0:
            if (max - min == 3)
                return true;
            break;
        case 1:
            if (max - min == 2)
                return true;
            break;
        case 2:
            if (max - min == 4)
                return true;
            break;
        case 3:
            if (max - min == 1)
                return true;
            break;
    }
    return false;
}

十道题,每道题的算法代码写完了,接下来需要遍历所有的选项,每4个就进一个,4进制。
给所有的答案赋值。从第一道题开始赋值。并不知道每道题的值是多少,所以叫穷举啊,瞎几把赋值,挨个尝试

public bool Add()
{
    for (int i = 0; i <10; i++)
    {
        if (answer[i] < 3)
        {
            answer[i]++;
            break;
        }

        if (answer[i] == 3)
        {
            if (i == 9)
                return false;
            answer[i] = 0;
        }
    }
    return true;
}

每道题都要返回true或者false,还要判断十道题是不是全部正确,如果上面的赋值,十道题都对上了,那就解出来。

public bool isRight()
{
    if (T1() && T2() && T3() && T4() && T5() && T6() && T7() && T8() && T9() && T10())
        return true;
    return false;
}

由于answer数组里面存放的是0,1,2,3,要把他们转换成对应的选项ABCD,才能直的看

public void Print()
{
    foreach (var i in answer)
    {
        switch(i)
        {
            case 0: Console.Write("A  ");break;
            case 1: Console.Write("B  "); break;
            case 2: Console.Write("C  "); break;
            case 3: Console.Write("D  "); break;
        }
    }
    Console.WriteLine();
}

然后就是在Main函数里面运行了

    int count = 0;//计算次数
    Program p = new Program();
    do
    {
        count++;
        if (p.isRight())
        {
           p.Print();
            Console.WriteLine("一共计算了:{0}次",count);
            break;
        }
    } while (p.Add());

结束。解题思维其实就是把每道题的条件用代码写出来,让计算机去不断地尝试,对比。仅限于计算量不大的情况下用穷举。
2018tuili.png

如果对你有帮助,打钱

赞赏



Responses
  1. 这两天在看美人为馅。哈哈

    Reply
  2. 有丶cool

    Reply