[思维]CodeForces 156B Suspects

题意:

有n个嫌疑犯,现在他们说出情况+a[i]表示说a[i]犯罪了,-a[i]表示说a[i]没有犯罪。其中只有一个是罪犯,并且有且只有m个人说的是真话,问最后谁在说谎,谁在说真话,谁的话又是不确定的。

分析:

刚开始拿到这个题,感觉很难下手,想到如何判定凶手的时候就会觉得很烦,大概是有感情因素在里面吧,不够有条理性。

首先假设有5个人,那么说出的情况可能是-1,+1,-2,+2,-3,+3,-4,+4,-5,+5 那么假设1 是凶手,说真话的人必定是m个。好的,那么这个时候说真话的人是(确定是+1的)+(确定其他是负值)的情况和。如果这个和为m,那么这个人是罪犯,如果罪犯的人数大于一,那么谁不是罪犯依然可以确定,但是如果谁是罪犯那就不确定了。

最后再根据每个人说的和实际情况的对比,如果不一致就是撒谎,一致就是说真话,罪犯大于一的时候罪犯不能确定,其他情况可以确定。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <utility>
#include <stack>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define write freopen("output.txt","w",stdout)
#define LL long long
using namespace std;
typedef pair<int, int> pii;
const int inf = 0x7fffffff;
const int maxn = 10005;
const int mod = 1000000007;
int a[maxn],b[maxn],c[maxn],sc[maxn];
int vis[maxn];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int i,j;
        memset(sc,0,sizeof(sc));
        memset(vis,0,sizeof(vis));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]>0)b[a[i]]++;
            else c[-a[i]]++;
        }
        int cnt=0;
        for(i=1;i<=n;i++)sc[i]=sc[i-1]+c[i];
        for(i=1;i<=n;i++)
        {
            if(b[i]+sc[i-1]+sc[n]-sc[i]==m)
            {
                vis[i]=1;
                cnt++;
            }
        }
        for(i=1;i<=n;i++)
        {
            if(a[i]>0 && (vis[a[i]]==0))puts("Lie");
            else if(a[i]<0 && vis[-a[i]]==0)puts("Truth");
            else if(a[i]>0 && (vis[a[i]]==1))
            {
                if(cnt>1)puts("Not defined");
                else puts("Truth");

            }
            else if(a[i]<0 && vis[-a[i]]==1)
            {
                if(cnt>1)puts("Not defined");
                else puts("Lie");
            }
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-10 08:46:41

[思维]CodeForces 156B Suspects的相关文章

Codeforces 156B Suspects——————【逻辑判断】

Suspects Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description As Sherlock Holmes was investigating a crime, he identified n suspects. He knows for sure that exactly one of them committed the crime. T

[思维]CodeForces 135B

题意: 给出8个点,问能否分成两个集合,使得一个组成正方形,另一个组成矩形.如果能,就输出YES,并且输出两个集合分别是什么,如果能,那就直接输出NO: 分析: 本来觉得这题很烦,没什么兴趣做了,浏览status的时候,偶然发现某final爷的id,点进去亮瞎了双眼...代码精简美观,思路一样很暴力,但是暴力的漂亮,于是乎学习了一下. 思路就是判断所有的边的可能排列,然后根据边判断,不用什么点积来做了.亲测正常点的做法起码要100++,细节错误的话还容易WA.这样暴力的话就不用烦恼这些了. #i

CodeForces839B[思维] Codeforces Round #428 (Div. 2)

#include <bits/stdc++.h> using namespace std; int n, k; const int MOD = 1000000007; int a[105], cnt[5]; void solve() { int t; cnt[4]=n,cnt[2]=2*n; for(int i=0;i<k;i++){ t=min(a[i]/4,cnt[4]); a[i]-=4*t; cnt[4]-=t; } cnt[2]+=cnt[4]; cnt[1]+=cnt[4];

Codeforces 433C. Ryouko&#39;s Memory Note (中位数,瞎搞,思维)

题目链接: http://codeforces.com/problemset/problem/433/C 题意: 给你一堆数字,允许你修改相同的数字成为别的数字,也可以修改成自己,问你修改后相邻数字的距离的绝对值的和最小是多少. 思路: 首先明确一个结论,一个数轴上一些点,要求一个与他们距离之和尽量小的点,那么这个点就是这些点的中位数,即排序后位于中间的数. 这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组.然后为了使得距离之和最短,要取中位数.在一串数字中,距所有数

Codeforces Round #423 (Div. 2) C 思维,并查集 或 线段树 D 树构造,水

Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) C. String Reconstruction   思维,并查集 或 线段树 题意:一个字符串被删除了,但给出 n条信息,要还原出可能的字典序最小的字符串.信息有:字符串ti,ki个位置xi,表明原本的字符串在xi位置是以字符串ti开头的. tags:惨遭 fst,一开始把所有字符串都存下来,排序做的,结果爆内存了.. 方法1: 考虑并查集,对于字符串 ti,在位置xi,

贪心/思维题 Codeforces Round #310 (Div. 2) C. Case of Matryoshkas

题目传送门 1 /* 2 题意:套娃娃,可以套一个单独的娃娃,或者把最后面的娃娃取出,最后使得0-1-2-...-(n-1),问最少要几步 3 贪心/思维题:娃娃的状态:取出+套上(2),套上(1), 已套上(0),先从1开始找到已经套好的娃娃层数, 4 其他是2次操作,还要减去k-1个娃娃是只要套上就可以 5 详细解释:http://blog.csdn.net/firstlucker/article/details/46671251 6 */ 7 #include <cstdio> 8 #i

codeforces 349B Color the Fence 贪心,思维

1.codeforces 349B    Color the Fence 2.链接:http://codeforces.com/problemset/problem/349/B 3.总结: 刷栅栏.1-9每个字母分别要ai升油漆,问最多可画多大的数字. 贪心,也有点考思维. #include<bits/stdc++.h> using namespace std; #define LL long long #define INF 0x3f3f3f3f int main() { int v,a[1

codeforces 848B Rooter&#39;s Song 思维题

http://codeforces.com/problemset/problem/848/B 给定一个二维坐标系,点从横轴或纵轴垂直于发射的坐标轴射入(0,0)-(w,h)的矩形空间.给出点发射的坐标轴,位置,延迟时间,发生碰撞则交换方向.求最后每个点的射出位置. 首先我们观察能得出两个结论,1. 类似蚂蚁爬树枝的问题,相遇只会交换方向,所以最后的射出点集只会因为碰撞而改变动点与射出点的对应关系,而不会增加减少射出点集.2.我们根据其射入位置和延迟时间可以计算出一个值v=pos-time,只有这

Codeforces Round #459 (Div. 2) C 思维,贪心 D 记忆化dp

Codeforces Round #459 (Div. 2) C. The Monster 题意:定义正确的括号串,是能够全部匹配的左右括号串. 给出一个字符串,有 (.). ? 三种字符, ? 可以当作 ( 可 ) . 问这个字符串有多少个子串是正确的括号串. tags:好考思维,想不到.. 预处理出每个字符向左向右最多可以匹配到哪里,再 O(n*n) 枚举所有区间,看是否符合条件. // C #include<bits/stdc++.h> using namespace std; #pra