猜凶手和猜名次

Posted 两片空白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了猜凶手和猜名次相关的知识,希望对你有一定的参考价值。

一.猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

解题思路:

        遍历A~D为凶手的所有情况,确定符合情况的凶手。

        如何确定符合情况?

                已知3个人说了真话,1个人说的是假话。将题意转化为代码

//符合条件,一个人说假话三个人说真话,逻辑运算在c语言中,真的情况为1,假的情况为0
//等于3说明一个人说的假话
if ((Killer != 'A') + (Killer == 'C') + (Killer == 'D') + (Killer != 'D') == 3);

                利用逻辑运算做加法,来确定3个人说了真话,1个人说的是假话。

#include<iostream>
#include<vector>
#include<string>
using namespace std;

void GuessKiller(){
	char Killer = 'A';//凶手
	for (; Killer <= 'Z'; Killer++){//遍历所有凶手的情况
		//符合条件,一个人说假话三个人说真话,逻辑运算在c语言中,真的情况为1,假的情况为0
		//等于三说明一个人说的假话
		if ((Killer != 'A') + (Killer == 'C') + (Killer == 'D') + (Killer != 'D') == 3){
			cout << Killer << endl;
		}
	}
}


int main(){
	GuessKiller();

	getchar();
	return 0;
}

   二.猜名次

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:

A选手说:B第二,我第三;

B选手说:我第二,E第四;

C选手说:我第一,D第二;

D选手说:C最后,我第三;

E选手说:我第四,A第一;

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

解题思路:

        利用全排列,列出所有情况

        用数组vector<int> path来保存名次1~5,下标0~4表示A~E

        收集结果时,

        首先不会出现一个人说的都对的情况

        其次:找出符合说法的情况

#include<iostream>
#include<vector>
#include<string>
using namespace std;

vector<int> path;//保存元素
vector<int> key;//保存是否使用过。0未使用,1使用
//回溯算法
void BackTracing(vector<int>& str){
	//终止
	if (path.size() == str.size()){
		//不会有一个人说法都对的情况
		if ((path[0] == 3 && path[1] == 2) || (path[1] == 2 && path[4] == 4) \\
			|| (path[2] == 1 && path[3] == 2) || (path[2] == 5 && path[3] == 3) \\
			|| (path[4] == 4 && path[0] == 1)){
			return;
		}
		//找出符合条件的排名
		if ((path[0] == 3 || path[1] == 2) && (path[1] == 2 || path[4] == 4) \\
			&& (path[2] == 1 || path[3] == 2) && (path[2] == 5 || path[3] == 3) \\
			&& (path[4] == 4 || path[0] == 1)){
			char i = 'A';
			for (const auto& c : path){
				cout << i << "=" << c << endl;
				i++;
			}
            exit(0);//得到结果退出进程
  		}
  		return;
  	}
  
  	//全排列,
  	for (int i = 0; i < str.size(); i++){
  		if (key[i] == 0){
  			key[i] = 1;
			path.push_back(i + 1);
			//递归
			BackTracing(str);
			//回溯
			key[i] = 0;
			path.pop_back();
		}
	}
}

void GuessRank(vector<int>& str){
	int len = str.size();
	key.resize(len);
	BackTracing(str);
}

int main(){
	int arr[] = { 1, 2, 3, 4, 5 };
	vector<int> people(arr, arr + sizeof(arr) / sizeof(int));
	GuessRank(people);
	getchar();
	return 0;
}

以上是关于猜凶手和猜名次的主要内容,如果未能解决你的问题,请参考以下文章

C语言编程解趣题系列——找凶手和比赛名次

c语言期末考试压轴编程题——猜凶手猜名词喝汽水水仙花数

c语言期末考试压轴编程题——猜凶手猜名词喝汽水水仙花数

c语言期末考试压轴编程题——猜凶手猜名词喝汽水水仙花数

猜凶手游戏

解猜数字(XAXB)