前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1089 狼人杀-简单版 (20 分)

1089 狼人杀-简单版 (20 分)

作者头像
韩旭051
发布2019-11-08 01:08:43
5010
发布2019-11-08 01:08:43
举报
文章被收录于专栏:刷题笔记刷题笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://cloud.tencent.com/developer/article/1535059

1089 狼人杀-简单版 (20 分)

以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?

本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?

输入格式:

输入在第一行中给出一个正整数 N(5≤N≤100)。随后 N 行,第 i 行给出第 i 号玩家说的话(1≤i≤N),即一个玩家编号,用正号表示好人,负号表示狼人。

输出格式:

如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a1,...,aM 和 B=b1,...,bM,若存在 0≤k<M 使得 ai=bi (i≤k),且 ak+1<bk+1,则称序列 A 小于序列 B。若无解则输出 No Solution

输入样例 1:

代码语言:javascript
复制
5
-2
+3
-4
+5
+4

输出样例 1:

代码语言:javascript
复制
1 4

输入样例 2:

代码语言:javascript
复制
6
+6
+3
+1
-5
-2
+4

输出样例 2(解不唯一):

代码语言:javascript
复制
1 5

输入样例 3:

代码语言:javascript
复制
5
-2
-3
-4
-5
-1

输出样例 3:

代码语言:javascript
复制
No Solution

先放答案

代码语言:javascript
复制
#include<iostream>
#include<vector>
using namespace std;
int main(){
	int n;
	int v[105];
	int a[105];
	cin>>n;
	for(int i=1;i<=n;i++){ 
	cin>>v[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			for(int l=1;l<=n;l++){
				a[l]=1;
			}
		
		vector<int>lie;
		a[i]=-1;
		a[j]=-1;
		for(int k=1;k<=n;k++){
			//cout<<v[k]<<" "<<a[abs(v[k])]<<"*";
			if(v[k]*a[abs(v[k])]<0){
			lie.push_back(k);
			}
		//printf("%2d",a[k]);
		}
		//cout<<" "<<lie.size()<<endl;
		if(lie.size()==2&&a[lie[0]]*a[lie[1]]==-1){
			cout<<i<<" "<<j;
			return 0;
		}
	}
	}
	cout << "No Solution";
	return 0;
} 

再放柳神的超级简洁的答案(我抄的她的)

水平高下立刻见

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<int> v(n+1);
    for (int i = 1; i <= n; i++) cin >> v[i];
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            vector<int> lie, a(n + 1, 1);
            a[i] = a[j] = -1;
            for (int k = 1; k <= n; k++)
                if (v[k] * a[abs(v[k])] < 0) lie.push_back(k);
            if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0) {
                cout << i << " " << j;
                return 0;
            }
        }
    }
    cout << "No Solution";
    return 0;
}

一道20分的简单题,活生生的写了1小时20分钟

这是我的做题流程

直接按照题目说的,直接暴力编程,能过一部分测试点,那儿不会也查不出来,因为太乱了

代码语言:javascript
复制
#include<iostream>
#include<algorithm>
using namespace std;
int sum[105];
int person[105];
struct zong{
	int a;
	int b;
};
zong z[1000];
int cou=0;
int cmp(zong z1,zong z2){
	if(z1.a==z2.a){
		return z1.b<z2.b;
	}else{
		return z1.a<z2.a;
	}
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sum[i];
	}//存入信息
	for(int i=1;i<=n;i++){
		//撒谎狼人循环
		for(int k=1;k<=n;k++){//撒谎好人循环 
			if(k==i){
				continue;
			}
			//判断能否出答案
			for(int l=1;l<=n;l++){
				//清零
				person[l]=0;
			} 
			for(int l=1;l<=n;l++){
				
				//存入推理信息
				if(l==i||l==k){
					int s=sum[l];//撒谎的人说的
					if(s<0){
						//撒谎的说是坏人,就是好人 
						if(person[-s]==-1 ){
							person[i]=1;
						}
						person[-s]=1; 
					} else{
						// 撒谎的说是好人,就是坏人 
						if(person[s]==1 ){
							person[i]=1;
						}
						person[s]=-1;
					}
					
				} 
				else{
					
					int s=sum[l];//撒谎的人说的
					if(s<0){
						if(person[-s]==1 ){
							person[i]=1;
						}
						//说是坏人,就是坏人 
						person[-s]=-1; 
					} else{
						// 说是好人,就是好人 
						if(person[s]==-1 ){
							person[i]=1;
						}
						person[s]=1;
					}
				} 
				
				
			}
			if(person[i]==0){
				person[i]=-1;
			}
			if(person[i]!=-1){
				continue;
			}
			//推一下,有没有答案
				int huai[100];
				int huaicount=0;
				for(int l=1;l<=n;l++){
					//printf("%2d ",person[l]); 
					if(person[l]==-1){
						huai[huaicount++]=l;
					}
				}  
				//cout<<endl;
				if(huaicount==2){
					//cout<<"判断"<<huai[0]<<" "<<huai[1]<<"sahuang"<<i<<" "<<k<<endl;
					if(huai[0]!=k&&huai[1]!=k){
						if(huai[0]==i||huai[1]==i){
							//cout<<huai[0]<<" "<<huai[1]<<endl;
							z[cou].a=huai[0];
							z[cou++].b=huai[1];
							
							//return 0;
						}
					}
				}
		} 
	} 
	sort(z+0,z+cou,cmp);
	if(cou>0){
		cout<<z[0].a<<" "<<z[0].b;
		return 0;
	}
	cout<<"No Solution";
	return 0;
} 

紧接着搜索柳神的代码

学习一波自己敲还是错误百出....人家STL容器选的就是很适合。

柳神是直接遍历两个狼人去试探,我是直接遍历两个说谎的人去试探。

问题主要(我已经发现的)出在了答案不唯一的输出上,

如果解不唯一,则输出最小序列解

柳神的方法,直接从最小的1,2 开始算只要出现解,就是最小解

而我的方法,使用1 ,2 说谎开始算的,要输出最小解,就需要遍历所有的答案,最后还要排序啥的,一堆事情,最后才能输出最小解。

说明还是做得题少,多做,多思考。争取下一道做上来。

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<int> v(n+1);
    for (int i = 1; i <= n; i++) cin >> v[i];//存进来
	for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
        	vector<int> lie, a(n + 1, 1);//默认都是好人 
            a[i] = a[j] = -1;//两个坏人 
            for (int k = 1; k <= n; k++){
			
                if (v[k] * a[abs(v[k])] < 0) lie.push_back(k);//v[k]是k说的话,a[abs (v[k])],是哪个人的真是情况实物与存的信息不符,存进谎话里 
        }
        
			if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0) {//谎话的1.两个人,2.一个好人一个坏人 
                cout <<i<<" "<< j;//输出坏人 
                return 0;
            }
        }
    }
    cout << "No Solution";
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1089 狼人杀-简单版 (20 分)
    • 输入格式:
      • 输出格式:
        • 输入样例 1:
          • 输出样例 1:
            • 输入样例 2:
              • 输出样例 2(解不唯一):
                • 输入样例 3:
                  • 输出样例 3:
                    • 先放答案
                      • 再放柳神的超级简洁的答案(我抄的她的)
                        • 水平高下立刻见
                      • 一道20分的简单题,活生生的写了1小时20分钟
                        • 这是我的做题流程
                      • 直接按照题目说的,直接暴力编程,能过一部分测试点,那儿不会也查不出来,因为太乱了
                        • 紧接着搜索柳神的代码
                          • 学习一波自己敲还是错误百出....人家STL容器选的就是很适合。
                            • 柳神是直接遍历两个狼人去试探,我是直接遍历两个说谎的人去试探。
                            • 问题主要(我已经发现的)出在了答案不唯一的输出上,
                              • 如果解不唯一,则输出最小序列解
                                • 柳神的方法,直接从最小的1,2 开始算只要出现解,就是最小解
                                • 而我的方法,使用1 ,2 说谎开始算的,要输出最小解,就需要遍历所有的答案,最后还要排序啥的,一堆事情,最后才能输出最小解。
                              • 说明还是做得题少,多做,多思考。争取下一道做上来。
                              相关产品与服务
                              容器服务
                              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档