zoukankan      html  css  js  c++  java
  • 【模拟赛·食物中毒】

    背景

    WZOI的小组成员今天集体食物中毒,什么事情也不能干了,这是一件十分可怕的事。幸亏WZOI的Bqc同志十分在行化学,他可以马上制作出解药来……

    问题描述

    Bqc经过一段时间的研究发现,要解这种毒需要一种特殊的药物。不幸的是,这种药物在市面上不存在,没有办法Bqc只好亲自制得这种药物。它含有M种化学物质A1,A2,…,AM。现在Bqc的手上有N种药材(每种药材只有一种),每种药材含有若干种化学物质(Bqc他有一种机器,只要将药材放入机器,就能制得相应的药物)。 Bqc需要你的帮助,他希望你能帮他选取若干种药材,用这些选取的药材制作出Bqc需要的药物。由于这些化学物质是有毒的,因此你选出来的药物,必须含有这M种化学物质。有一点需要注意:根据中医以毒攻毒的理论,两个相同的化学物质在一起,它们的药性会同时消失变为一种无毒物质(大多情况下这种无毒物质会挥发掉,也就是说这种化学物质消失了)。比如说药材1有化学物质1、2,药材2有化学物质1、3,那么如果药材1和药材2混合,你得到的药物会含有化学物质2、3。 Bqc问你,需要选用那些药材可以制得他想要的药物?

    输入格式

    本题每个测试点存在多组数据,每组输入数据第1行包含两个整数N和M,表示Bqc拥有的药材数目和他所需药物所含的化学物质的种类数目; 第2行共有M个整数,分别表示M中化学物质的编号,用1~50之间的数字编号(输入数据保证同一种化学物质不会被描述多次); 第3行到第N+2行,每行包含若干个数。第i+2行的第一个数为Mi,表示药材i包含Mi中化学物质,接下来Mi个数,描述药材i含有的化学物质的编号,用1~50之间的数字编号(同一种化学物质可能会被描述多次)。 每组输入数据用一个空行隔开。输出格式对于每组数据输出一行,如果用这些药材可以制得Bqc需要的药物,那么输出“Possible”;否则输出“Impossible”,不包含引号。

    样例输入

    输出

    medicine.in

    medicine.out

    2 2 2 3 2 1 5 2 1 3 3 3 1 3 4 4 2 3 4 1 1 4

    Impossible

    Possible

    Possible

    3 样例解释对于样例的第三组数据,可行的方案有选取 1、3 和选取 2、4. 数据规模对于30%的数据,N≤10,M≤20;对于50%的数据,N≤20,M≤40;对于100%的数据,N≤20,M≤50;对于100%的数据,Mi≤50。保证测试数据的组数不超过100。时间限制 1s 提示同一种化学物质被描述偶数次,那么说明这种物质不存在;否则这种物质存在。

    【题解】

          ①STD:暴搜,时间复杂度由于有T的存在是O(108)左右

          ②我:

                  由于只管治病的物质,因此将治病的物质编号压入线性基,

                  然后查询能否构造11111……1111就是了。时间复杂度O(5*106)

    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    #define Xor go(j,1,m)x[j]^=A[i][j]
    #define go(i,a,b) for(int i=a;i<=b;i++)
    int n,m,a[103],M,t,index[103],x[55];bool Prior[103];
    
    struct Linear_Base
    {
    	int A[55][55],have[55];
    	void Clear(){go(i,1,m){have[i]=0;go(j,1,m)A[i][j]=0;}}
    	void Insert()
    	{
    		go(i,1,m)if(x[i]){if(!have[i]){have[i]=1;
    		go(j,1,m)A[i][j]=x[j];i=m;}else Xor;}
    	}
    	bool Capable()
    	{
    		go(i,1,m)if(x[i]&&A[i][i])Xor;
    		int sum=0;go(i,1,m)sum+=x[i];return sum==0;
    	}
    }Tool;
    
    int main()
    {
    	freopen("medicine.in","r",stdin);
    	freopen("medicine.out","w",stdout);
    	
    	while(~scanf("%d%d",&n,&m))
    	{
    		Tool.Clear();
    		memset(Prior,0,sizeof(Prior));
    		go(i,1,m)scanf("%d",a+i),Prior[a[i]]=1;
    		std::sort(a+1,a+m+1);go(i,1,m)index[a[i]]=i;
    		go(i,1,n){scanf("%d",&M);memset(x,0,sizeof(x));
    		go(i,1,M){scanf("%d",&t);if(Prior[t])x[index[t]]^=1;}
    		Tool.Insert();}go(i,1,m)x[i]=1;puts(Tool.Capable()?"Possible":"Impossible");
    	}
    	return 0;
    }//Paul_Guderian
    

    .

  • 相关阅读:
    android焦点
    URI和URL的区别比较与理解
    Android Bundle类
    repo命令
    ubuntu adb找不到设备
    【python】-网络编程
    【python】-反射
    【python】-类的特殊成员方法
    【python】-7-面向对象的进阶
    【python】-多态
  • 原文地址:https://www.cnblogs.com/Damitu/p/7778139.html
Copyright © 2011-2022 走看看