⭐⭐⭐⭐⭐PAT A1148 Werewolf - Simple Version

本文深入解析了一道名为“Werewolf-SimpleVersion”的编程题,通过暴力枚举策略找到两个狼人的身份。文章详细展示了两种不同的代码实现方式,包括作者初次尝试时的复杂解法和第二次理解题解后的简洁暴力枚举法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

1148 Werewolf - Simple Version (20分)

知识点

思维

实现

码前思考

  1. 这道题目我没有写出来,谁tm能够想到这是一道暴力题呢?!
  2. 好吧,这个数据最大是100, O ( N 3 ) O(N^3) O(N3)的话就是 1 0 6 10^6 106,没有超出1s的限制,不知道会不会超出400ms的限制;
  3. 居然是暴力,下面是柳神的解答:
    在这里插入图片描述
  4. 关键就是要先自己假设好谁是狼人,谁是人,然后他们说的话,看其中说谎的有多少个。。。

代码

//数组下标从1开始 
#include "bits/stdc++.h"
using namespace std;
const int maxn = 1e2+10;

int rool[maxn];
int input[maxn];
int tmp[maxn];
int n;
 
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&input[i]);
	}	
	
	int i;
	int j;
	bool find = false; 
	for(i=1;i<=n;i++){
		for(j=i+1;j<=n;j++){
			fill(rool,rool+maxn,1);
			//设置角色,i,j为狼人 
			rool[i] = -1; 
			rool[j] = -1;
			//其他的都是好人
			
			//接下来只允许狼人和好人各撒一次谎
			int cntW=0;
			int cntH=0; 
			 
			bool flag = true; 
			for(int k=1;k<=n;k++){
				//表示当前的角色 
				int cur = abs(input[k]);
				int curRool = input[k]/cur;
				 
				if(k==i || k==j){
					//是狼人 
					if(curRool != rool[cur]){
						//出现不一致
						if(cntW==0){
							cntW++;
						}else{
							//这种情况要舍弃
							flag = false;
							break; 
						} 
					}
				}else{
					//不是狼人
					if(curRool != rool[cur]){
						//出现不一致
						if(cntH==0){
							cntH++;
						}else{
							//这种情况要舍弃
							flag = false;
							break; 
						} 
					}					 
				}
			}
			
			//如果撒谎没到1个
			if(cntW != 1||cntH!=1){
				flag=false;
			} 
			
			//那么要中断 
			if(flag == true){
				find = true;
				break;
			} 
		}
		if(find == true){
			break;
		} 
	}
	
	if(find == true){
		printf("%d %d",i,j);
	}else{
		printf("No Solution");
	}
	
	return 0;
}

码后反思

  1. 好菜呀。。。

二刷代码

我第二次还是没写出来,但是看了题解之后发现真的还是暴力啊,这太无语了,直接暴力枚举。

还有就是,我第一次写的那个东西是个啥?又臭又长

//暴力枚举所有狼人的情况,然后判断谁说谎了。。。 
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e2+10;

int n;
int v[maxn];
int gt[maxn];
vector<int> vt;

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&v[i]);	
	}
	
	//接下来暴力枚举所有情况
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			fill(gt,gt+maxn,1);
			gt[i] = -1;
			gt[j] = -1;
			vt.clear();
			
			//然后开始遍历判断谁说谎了
			for(int k=1;k<=n;k++){
				if( (v[k]/abs(v[k])) != gt[abs(v[k])] ){ //首先是取符号 
					//printf("%d\n",k);
					vt.push_back(k);
				}		
			}
			
			//首先检查是否有两个元素
			if(vt.size()==2){
				//接下来检查两个元素是否是相反的符号
				if(gt[vt[0]] + gt[vt[1]] == 0){
					printf("%d %d",i,j);
					return 0;
				}	
			} 
		}
	}
	
	printf("No Solution\n"); 
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值