当前位置: 首页 > news >正文

算法题解:找不到百草枯

问题描述:有瓶有毒药水不知道是那个。经过m次混和,求哪一次可以得到药水和药水的编号;否则,输出可能的药水编号。

思路:用dy表示当前可能为毒药的个数,notdy表示一定不是毒药的个数。同时开个vis数组,vis中0表示未知,1表示可能有毒,2表示一定没有毒。

​ 每次读入记录有毒次数。对有毒和无毒进行操作,得到dynotdy的个数。当且仅当dy == 1 || notdy == n - 1时可以得到答案,记录当前询问次数,之后在进行处理。

​ 不能准确判断是否有毒,按顺序进行遍历即可。

时间线性。

代码:

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <random>
#include <sstream>
#include <numeric>
#include <stdio.h>
#include <functional>
#include <bitset>
#include <algorithm>
using namespace std;

// #define Multiple_groups_of_examples
#define IOS std::cout.tie(0);std::cin.tie(0)->sync_with_stdio(false);
#define dbgnb(a) std::cout << #a << " = " << a << '\n';
#define dbgtt cout<<" !!!test!!! "<<endl;
#define rep(i,x,n) for(int i = x; i <= n; i++)

#define all(x) (x).begin(),(x).end()
#define pb push_back
#define vf first
#define vs second

typedef long long LL;
typedef pair<int,int> PII;

const int INF = 0x3f3f3f3f;
const int N = 5e5 + 21;
int vis[N]; // 0 未知 1 可能有毒 2 一定没毒
int cnt[N];
int a[N];
inline int fread() // 快读
{
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }
    return x * f;
}

void inpfile();
void solve() {
    int n,m; n = fread(), m = fread();
    // dy -- 是毒药的个数
    // notdy -- 不是毒药的个数
    // sum -- 查询中混有毒药的个数
    int sum = 0, dy = 0, notdy = 0;
    int tim = 0;
    for(int i = 0; i < m; ++i) {
        int k; k = fread();
        for(int j = 0; j < k; ++j) a[j] = fread();
        int isdu; isdu = fread();
        if(isdu) { // 如果是有毒药的话
            sum++; // 查询有毒药的次数 + 1
            int now = 0; // 判断可能是毒药的个数
            // 当sum更新,上一次可能是毒药的,这一次就可能不是了,因此需要一个now进行记录
            for(int j = 0; j < k; ++j) {
                cnt[a[j]]++; // 先将这个可能是毒药的次数+1
                if(vis[a[j]] == 2) continue; // 如果一定不是毒药
                if(cnt[a[j]] == sum) { // 是毒药的判断是:该药编号 在查询有毒药的询问中都出现,即等于sum
                now++; // 如果满足,now 新的dy加1
                vis[a[j]] = 1; // 将这个设置为可能是毒药
                } else { // 否则就一定不是毒药
                    vis[a[j]] = 2;
                    notdy++;
                }
            }
            // 将新的查询回合中可能是毒药的次数进行更新
            dy = now;
        } else { // 如果这里没有毒药,就简单了
            for(int j = 0; j < k; ++j) {
                if(vis[a[j]] != 2) notdy++; // 如果不是 2, notdy++
                if(vis[a[j]] == 1 && cnt[a[j]] == sum) dy--; // 如果是1,需要将毒药个数-1
                vis[a[j]] = 2; // 设置为 一定没有毒药
            }
        }
        if(dy == 1 || notdy == n - 1) { // 如果dy个数为1,或者 一定不是毒药的个数为 n - 1
            tim = i + 1; // 一定可能判断出毒药
            break;
        }

    }
    if(tim) { // 如果找到了毒药
        puts("Yes");
        printf("%d ",tim);
        for(int i = 1; i <= n; ++i) {
            // 找到每次查询是毒药时都出现的那个药,并且这个编号一定是毒药(多余了感觉
            if(cnt[i] == sum && vis[i] != 2) { 
                cout<<i;
                return ;
            }
        }
    } else {
        puts("No");
        for(int i = 1; i <= n; ++i) {
            // 否则,将可能是毒药的进行输出
            if(vis[i] != 2 && cnt[i] == sum) {
                printf("%d ", i);
            }
        }
    }
}
int main()
{
    #ifdef Multiple_groups_of_examples
    int T; cin>>T;
    while(T--)
    #endif
    solve();
    return 0;
}
void inpfile() {
    #define mytest
    #ifdef mytest
    freopen("ANSWER.txt", "w",stdout);
    #endif
}

/**
 * 


3 2
2 1 2 1
2 2 3 1

Yes
2 2
*/

相关文章:

  • 打破常规,BD仓储物流的效能提升!
  • vue3的v-model使用
  • 【React】增量传输与渲染
  • 在双十一必买的好物有哪些?盘点五大必买好物清单!
  • K8S简介及其部署
  • 深度学习:监督学习(Supervised Learning)详解
  • 量化交易里面的挂单成交率大概是多少呢
  • Kubernetes(K8s)的简介
  • SafeLine - 雷池 - 不让黑客越过半步
  • 无人机之飞控仿真技术篇
  • 【需求分析】软件系统需求设计报告,需求分析报告,需求总结报告(原件PPT)
  • Blade 模板引擎中常用的指令和标签
  • 招联2025校招内推倒计时
  • 计算机网络:计算机网络概述:网络、互联网与因特网的区别
  • SpringBoot访问web中的静态资源
  • JavaScript中的运算符
  • 数据结构C语言版
  • C++知识总结
  • vue2面试题
  • Unity 快速定位到目标文件夹
  • 中国词学研究会原会长、华东师大教授马兴荣逝世,享年101岁
  • 中国一重集团有限公司副总经理陆文俊被查
  • 金地集团:今年前4个月实现销售额109.3亿元,同比下降52.44%
  • 美众议院通过法案将“墨西哥湾”更名为“美国湾”
  • 视频丨习近平主席出席俄方在机场举行的迎宾仪式
  • 杭温高铁、沪苏湖高铁明起推出定期票和计次票,不限车次执行优惠折扣