原来自己不是什么好人

面对自己心仪的女生而不敢去追求的人很痛苦,一个有老婆的人当面对一个令自己心仪的女生时会更痛苦。

很拼的一个女生,她的眼里没有其他的,只会看向前方,向着自己的目标马力全开。

完美的诠释了女版的拼命三郎,很欣赏她但不敢接近她。

当我察觉到自己的有一些喜欢她的时候,我才发现自己确实不是什么好人。

既然已经有了女朋友的人,为何还会对别的女生动心,这种事情对谁都没有好处吧。

所以只有将它深深地埋藏在心底,压抑着、隐藏着,我更期待它的发霉腐烂,若是生根发芽了的话,那真对我不忠的惩罚。


我知道自己还入不了她的“法眼”,可能自己根本就不是她中意的类型,但还是想让自己变得更优秀。

距离她的标准近那么一点点,戒烟、戒酒、多运动、生活作息规律,做这些的时候我自己感觉很羞愧,因为我从未想过为我的女朋友改变过什么。

我只是承诺她锦衣玉食,承诺她富贵荣华,但从没想过自己要为她改变些什么。


以前经常告诫自己:男儿志在四方,不应沉溺于儿女私情。所以即便是有了女朋友后,我也很少将心思放在那些悱恻缠绵上,男人应当以事业为重。

在就读高中时也曾遇到过一些自己心仪的女生,不过也不过是因为对方漂亮而已,是一种很肤浅的喜欢,能和女朋友走到一起,也是我的幸运。

可直到遇到她以后,我才明白为何很多大好男儿都难过情关。


相见不如不见,羞耻之心难以言表,谨以此文铭记,希望自己可以把她淡忘,不要做出既伤害自己又伤害别人的事情吧。

``` #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 110; bool wolf[N]; int a[N]; vector<int> liar; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ vector<int> liar; memset(wolf,0,sizeof wolf); wolf[i]=wolf[j]=true; for(int k=1;k<=n;k++){ if(wolf[abs(a[k])]^(a[k]<0)){ liar.push_back(k); } } if(liar.size()==2&&wolf[liar[0]]^wolf[liar[1]]){ for(int i=1;i<=n;i++){ if(wolf[i]) cout<<i<<' '; } return 0; } } } cout<<"No Solution"; return 0; }```“狼人杀”游戏分为狼人、好人两大阵营。 在一局“狼人杀”游戏中: 1 号玩家说:“2 号是狼人”; 2 号玩家说:“3 号是好人”; 3 号玩家说:“4 号是狼人”; 4 号玩家说:“5 号是好人”; 5 号玩家说:“4 号是好人”。 已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有且只有一只狼在说谎。 扮演狼人角色的是哪两号玩家? 本题是这个问题的升级版: 已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有且只有一只狼在说谎。 要求你找出扮演狼人角色的是哪几号玩家? 输入格式 输入在第一行中给出一个正整数 N 。 随后 N 行,第 i 行给出第 i 号玩家说的话(1≤i≤N ),即一个玩家编号,用正号表示好人,负号表示狼人。 输出格式 如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。 如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a[1],…,a[M] 和 B=b[1],…,b[M],若存在 0≤k<M 使得 a[i]=b[i](i≤k),且 a[k+1]<b[k+1],则称序列 A 小于序列 B 。 若无解则输出 No Solution。 数据范围 5≤N≤100 输入样例1: 5 -2 +3 -4 +5 +4 输出样例1: 1 4 输入样例2: 6 +6 +3 +1 -5 -2 +4 输出样例2(解不唯一): 1 5 输入样例3: 5 -2 -3 -4 -5 -1 输出样例3: No Solution
03-20
<think>嗯,我现在得仔细看看这个问题。题目是关于狼人杀的,已知有N个玩家,其中两个是狼人,有两个人在说谎,而且这两个说谎的人里恰好有一个是狼人。那我们的任务就是找出这两个狼人的编号。 首先,我得理解题目给出的代码逻辑。代码的大致思路应该是遍历所有可能的狼人组合,然后检查每个组合是否符合条件。那具体的步骤是怎么样的呢? 看代码的结构,主函数里有一个双循环,i从1到n,j从i+1到n,这应该是在枚举所有可能的两个狼人的组合,假设i和j是狼人。然后,对于每个这样的组合,程序会创建一个wolf数组,标记这两个人是狼。接下来,遍历每个玩家k,检查他们的陈述是否与实际情况相符。这里有个条件:wolf[abs(a[k])] ^ (a[k] < 0)。这可能是在判断玩家k的话是否为谎言。 让我仔细分析这个条件。a[k]是第k个玩家说的话,比如输入中的-2,表示他认为2号是狼人。那么,当a[k]是负数时,他认为abs(a[k])是狼人;如果是正数,则认为是好人。那么,wolf[abs(a[k])]的值表示该玩家是否真的是狼人。这时候,如果玩家k的话与实际是否相符呢? 比如,假设玩家k说“-x”,即认为x是狼人。那么如果wolf[x]是真(确实是狼人),那么他的话是对的;否则是错的。同样,如果他说“+x”,那么如果wolf[x]是假(x是好人),他的话是对的。所以,判断玩家k是否说谎的条件应该是:wolf[abs(a[k])]是否等于(a[k] > 0)。如果两者不一致,说明他在说谎。比如,a[k]是+3,即他说3是好人,如果wolf[3]是true(狼人),那么他撒谎了。因此,判断是否说谎的条件可以写成:wolf[abs(a[k])] != (a[k] > 0)。这个条件成立的话,k就是撒谎者。 在代码中,这个条件被写成了wolf[abs(a[k])] ^ (a[k] <0)。这里可能有点混淆。让我再仔细看看。因为a[k]<0的话,表示他说的是狼人。所以,如果a[k]<0,那么他认为abs(a[k])是狼人。此时,wolf[x]的真假应该等于这个判断。如果两者不同,则说谎。所以,正确与否的条件应该是:如果wolf[x]等于(a[k]<0吗?)或者等式是否成立? 或者,原条件是否正确?比如,假设玩家k的陈述是a[k],那么正确的条件应该是wolf[abs(a[k])]是否等于(a[k] >0)。例如,当a[k]是负数时,说明玩家k认为abs(a[k])是狼人,所以正确的条件应该是wolf[abs(a[k])]是否为真。因此,如果玩家k的话正确,则wolf[abs(a[k)]应该等于(a[k]<0)。比如,a[k]=-2,那么正确的话是2号是狼人。所以,wolf[2]应该是true,此时a[k]<0为真。所以,wolf[x] == (a[k]<0)是否成立?或者说,wolf[x]是否等于玩家k所声称的? 或者,正确的情况是:当玩家k的话正确时,wolf[x]的值应该等于玩家k所声称的是狼人。例如,玩家k的话是+3,那么正确的条件是wolf[3]是false(好人);如果是-3,则wolf[3]要是true。所以,正确的条件应该是wolf[x] == (a[k] <0)。因为当a[k]<0时,说明玩家k认为x是狼人,这时候wolf[x]应该为true才正确。反之,如果是正数,wolf[x]应该为false。所以,当wolf[x]与(a[k]<0)不相等时,玩家k在撒谎。此时,wolf[abs(a[k])] ^ (a[k]<0) 的结果是否为true?因为异或运算,当两个值不同时结果为true。所以,当wolf[x]与(a[k]<0)不同时,结果为true,这时候k是在说谎,被加入liar数组。 所以,代码中的这个条件是正确的,即如果wolf[x]与玩家k的声明不符,那么k是撒谎者。这一步是对的。 然后,收集所有撒谎者到liar数组中。之后,检查liar的大小是否为2,并且这两个撒谎者中恰好有一个是狼人。这里,条件写成liar.size()==2 && wolf[liar[0]] ^ wolf[liar[1]]。wolf数组标记的是是否是狼人,所以wolf[liar[0]]和wolf[liar[1]]分别代表这两个撒谎者是否是狼人。异或运算的结果为true当且仅当其中一个为true,另一个为false。所以,这条件确保恰好有一个撒谎者是狼人。这样符合题目中的条件:两个说谎的人中有且只有一个是狼人。 如果满足这些条件,那么当前的i和j就是可能的狼人组合。一旦找到,就输出并按顺序返回。否则继续枚举。此外,为了满足输出最小序列的条件,代码通过外层循环的i和j的枚举顺序(i从1到n,j从i+1到n),这样找到的第一个符合条件的组合就是字典序最小的,因为遍历顺序是按照递增的顺序进行的。 例如,当i=1,j=4时,输出1 4,这比i=2,j=3这样的组合更小,所以一旦找到符合条件的,就立即返回,从而保证了输出的是最小的序列。 那问题来了,用户给出的代码是否能够正确处理所有情况?比如,在样例输入1中,输出是1和4。那当i=1,j=4时,wolf数组设为true。然后遍历每个玩家k的话,判断他们是否说谎,收集到两个说谎者,并且其中一个是狼人,另一个是好人。假设这两个说谎者的身份满足条件,则输出结果。 现在,我需要确认这个逻辑的正确性。例如,当假设i和j是狼人,那么其他都是好人。然后,检查所有玩家的话是否符合说谎条件,收集说谎者列表。然后必须满足说谎者有两人,并且其中恰好一个狼人。 那么,这样的代码逻辑是正确的吗? 比如,题目中的条件是两个说谎者,其中恰好有一个是狼人。而狼人共有两人,所以这两个说谎者中有一个是狼人,另一个是好人。那么,这两个说谎者中,狼人的数目是1,好人的数目是1。代码中的条件wolf[liar[0]] ^ wolf[liar[1]]正好是这个条件。因为异或为真当且仅当两者不同。所以,当两个撒谎者中一个是狼人,另一个是好人时,条件成立。例如,如果第一个撒谎者是狼人(wolf值为true),第二个是好人(wolf值为false),异或结果为true。此时条件满足。反之,若两个都是狼人,异或结果为false。或者两个都是好人,异或结果为false。所以条件正确。 那整个逻辑是正确的。那问题可能出现在哪里? 比如,在代码中,当找到符合条件的i和j时,立即输出并返回。而外层循环的顺序是按照i从小到大,j从i+1到n的顺序,所以第一个满足条件的i和j的组合必然是最小的序列。因此,代码可以正确处理解不唯一的情况,保证输出最小的解。 综上,这个代码的思路是正确的。现在,我需要将代码的逻辑翻译成中文的解释,帮助用户理解。 现在,用户的问题是要理解这段代码,或者介绍它的工作原理。所以,我需要分步骤解释代码的结构,以及每个部分的作用。 首先,代码的大致结构如下: 1. 输入n,然后读取每个玩家的话到数组a中。 2. 枚举所有可能的两个狼人的组合(i和j),这里i从1到n,j从i+1到n,确保每个组合是唯一的,并且i<j,这样输出的顺序是递增的。 3. 对于每个假设的i和j是狼人的情况,初始化wolf数组,标记i和j为true(狼人),其他为false。 4. 遍历所有玩家k,检查他们的话是否为谎言。如果是,就将k加入liar数组。 5. 检查liar数组的大小是否为2,并且这两个说谎者中恰好一个是狼人,另一个是好人。如果是,就输出当前的i和j,并结束程序。 6. 如果所有组合都遍历完没有找到符合条件的,输出No Solution。 那么,这样的逻辑是否正确? 是的。因为题目要求恰好两个说谎者,且其中一个是狼人,另一个是好人。而狼人总共有两个,所以必须满足这两个条件。 接下来,我需要用中文逐步解释代码的执行流程,以及各个部分如何对应问题的条件。例如,外层循环枚举可能的狼人组合,然后内层循环检查每个玩家的陈述是否符合条件,收集说谎者,再验证条件是否符合。 可能需要注意的地方是,当玩家k自己是否是狼人不会影响他说的话是否为真,只与他说的内容是否正确有关。例如,狼人可以说真话或者假话,而好人只能说真话或者假话?不,不是。无论是否是狼人,只要他们的陈述是否符合事实。例如,如果一个狼人k说“x是狼人”,而x确实是狼人,那么他说的是真话。否则是假话。所以,狼人可能说谎或者不说谎,但题目中恰好有两个说谎者,其中一个是狼人,另一个是好人。 所以,代码中的判断条件是否正确?是的,它只关心陈述是否与实际情况相符,而不管说话者的身份。因此,说谎者的判断是正确的。 现在,如何将代码的结构与问题条件对应起来? 例如,问题条件中的两个狼人,代码枚举所有可能的两个狼人组合。对于每个组合,检查是否满足总共有两个说谎者,其中一个是狼人,另一个是好人。如果满足,则输出该组合。否则,继续枚举。 那么,代码的正确性在于,正确枚举所有可能情况,并且正确判断每个情况是否符合条件。因此,该代码能够正确解决题目所述的问题。 接下来,可能需要给出一个例子,比如样例输入1的情况: 输入是5个玩家,他们的话分别是-2、+3、-4、+5、+4。假设狼人是1和4。那么,wolf数组标记1和4为true。然后,检查每个玩家的话是否说谎。 玩家1的话是-2,即他说2是狼人。但根据假设,狼人是1和4,所以2是好人。因此,wolf[2]是false。玩家1的话是否正确?他的陈述是“2是狼人”,即a[1]=-2。因为wolf[2]是false,所以a[1]<0为true,所以正确的话应该是wolf[2]等于true吗?原条件判断是否正确? 原条件中的判断是wolf[abs(a[k])] ^ (a[k]<0),即如果两者不同,则为true,说明是谎言。例如,玩家1的话是-2,即abs(a[k])=2。wolf[2]是false。a[k]<0是true。因此,wolf[2](false)异或(true)得到true,所以玩家1在说谎。所以,玩家1会被加入liar数组。 玩家2的话是+3,即他认为3是好人。wolf[3]是false(因为狼人是1和4),所以他的陈述正确吗?是的,所以不会加入liar数组。 玩家3的话是-4,即他认为4是狼人。wolf[4]是true,所以他的陈述是对的。不会加入liar数组。 玩家4的话是+5,即他认为5是好人。wolf[5]是false,正确。所以陈述正确,不加入。 玩家5的话是+4,即他认为4是好人。但wolf[4]是true,所以他的陈述错误,会被加入liar数组。 此时,liar数组中有玩家1和5。他们的wolf值分别是wolf[1]=true,wolf[5]=false。所以,其中一个是狼人,另一个是好人。满足条件。因此,这种情况会被选中,输出1和4。 这样,代码的正确性得到了验证。 最后,代码中的处理逻辑是正确的,能够正确解决题目所述的问题。</think>该代码解决的是狼人杀游戏中的逻辑推理问题,需要找出两个狼人,且满足:共有2人说谎,其中恰好1个是狼人。以下是代码的详细分析: --- ### **解决思路** 1. **枚举所有可能的狼人组合** 使用双重循环遍历所有可能的两个狼人组合 `(i, j)`,确保 `i < j` 以保证输出有序。 2. **假设狼人身份,验证陈述矛盾** 对于每组假设的狼人 `i` 和 `j`,标记 `wolf[i] = wolf[j] = true`,表示这两个玩家是狼人。 3. **收集说谎者** 遍历所有玩家的陈述,判断是否与假设的狼人身份矛盾。若矛盾,则该玩家在说谎,加入 `liar` 数组。 4. **验证说谎条件** 检查 `liar` 数组是否满足: - 恰好有2人说谎。 - 说谎者中恰好1个是狼人,1个是好人(通过异或运算判断)。 5. **输出最小解** 由于按升序枚举狼人组合,第一个符合条件的组合即为字典序最小的解。 --- ### **代码关键步骤解析** ```cpp for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ // 假设i和j是狼人 wolf[i] = wolf[j] = true; vector<int> liar; // 遍历所有玩家的陈述 for(int k=1;k<=n;k++){ int x = abs(a[k]); // 判断陈述是否矛盾:wolf[x] 是否等于玩家k声称的身份 if(wolf[x] != (a[k] > 0)) { liar.push_back(k); } } // 验证条件:2人说谎,且1狼1好人 if(liar.size() == 2 && (wolf[liar[0]] != wolf[liar[1]])) { cout << i << " " << j; return 0; } // 重置狼人标记 wolf[i] = wolf[j] = false; } } ``` --- ### **复杂度分析** - **时间复杂度**:$O(N^3)$ 双重循环枚举狼人组合($O(N^2)$),每次遍历所有玩家验证陈述($O(N)$)。 - **空间复杂度**:$O(N)$ 用于存储每个玩家的陈述和狼人标记。 --- ### **正确性验证** 以样例输入1为例: ``` 输入: 5 -2 (玩家1说2是狼人) +3 (玩家2说3是好人) -4 (玩家3说4是狼人) +5 (玩家4说5是好人) +4 (玩家5说4是好人) ``` 假设狼人为1和4: - **玩家1** 说2是狼人(错误,实际2是好人)→ 说谎者。 - **玩家5** 说4是好人(错误,4是狼人)→ 说谎者。 - 说谎者中1是狼人,5是好人 → 满足条件。 代码正确找到解 `1 4`。 --- ### **总结** 该代码通过暴力枚举所有可能的狼人组合,结合逻辑判断高效筛选出符合题目条件的解。其核心在于正确分析陈述矛盾并验证说谎者的身份分布,确保输出最小字典序解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值