1080 - My Bad

A logic circuit maps its input through various gates to its output with no feedback loops in the circuit. The input and output are an ordered set of logical values, represented here by ones and zeros. The circuits we consider are comprised of and gates (which output 1 only when their two inputs are both 1), or gates (which output 1 when one or both of their inputs are 1), exclusive or (xor) gates (which output 1 only when exactly one of the two inputs is 1), and not gates (which output the complement of their single input). The figures below show two circuits.

\epsfbox{p4446.eps}

Unfortunately, real gates sometimes fail. Although the failures may occur in many different ways, this problem limits attention to gates that fail in one of three ways: 1) always inverting the correct output, 2) always yielding 0, and 3) always yielding 1. In the circuits for this problem, at most one gate will fail.

You must write a program that analyzes a circuit and a number of observations of its input and output to see if the circuit is performing correctly or incorrectly. If at least one set of inputs produces the wrong output, your program must also attempt to determine the unique failing gate and the way in which this gate is failing. This may not always be possible.

Input 

The input consists of multiple test cases, each representing a circuit with input and output descriptions. Each test case has the following parts in order.

  • A line containing three positive integers giving the number of inputs (N$ \le$8), the number of gates (G$ \le$19), and the number of outputs (U$ \le$19) in the circuit.
  • One line of input for each gate. The first line describes gate g1. If there are several gates, the next line describes gate g2, and so on. Each of these lines contains the gate type (a = andn = noto =or, and x = exclusive or), and identification of the input(s) to the gate. Gate input comes from the circuit inputs (i1i2, ...) or the output of another gate (g1g2, ...).
  • A line containing the numbers of the gates connected to the U outputs u1u2,.... For example, if there are three outputs, and u1 comes from g5u2 from g1, and u3 from g4, then the line would contain: 5 1 4
  • A line containing an integer which is the number of observations of the circuit's behavior (B).
  • Finally B lines, each containing N values (ones and zeros) giving the observed input values and Uvalues giving the corresponding observed output values. No two observations have the same input values.


Consecutive entries on any line of the input are separated by a single space. The input is terminated with a line containing three zeros.

Output 

For each circuit in the input, print its case number (starting with 1), followed by a colon and a blank, and then the circuit analysis, which will be one of the following (with # replaced by the appropriate gate number):

No faults detected 
Gate # is failing; output inverted 
Gate # is failing; output stuck at 0 
Gate # is failing; output stuck at 1 
Unable to totally classify the failure


The circuits pictured in Figure 1 and Figure 2 are used in the first and last sample test cases.

Sample Input 

2 2 1 
o i1 i2 
n g1 
2 
2 
1 0 0 
0 0 1 
2 1 1 
a i1 i2 
1 
1 
1 0 1 
2 1 1 
a i1 i2 
1 
2 
1 0 1 
1 1 1 
1 1 1 
n i1 
1 
2 
1 1 
0 0 
3 4 4 
n g4 
a i1 i2 
o i2 i3 
x i3 i1 
2 3 4 1 
4 
0 1 0 0 1 0 1
0 1 1 0 1 1 0
1 1 1 0 1 0 1
0 0 0 0 0 0 1
0 0 0

Sample Output 

Case 1: No faults detected 
Case 2: Unable to totally classify the failure 
Case 3: Gate 1 is failing; output stuck at 1 
Case 4: Gate 1 is failing; output inverted 
Case 5: Gate 2 is failing; output stuck at 0






#include<iostream>
#include<string>
#include<string.h>
#include<stdlib.h>
using namespace std;
struct dat_edge
{
	int aim,last;
}edge[201];

int n,m,k,inde[101],coun[101],tmp_coun[101],pl[101],len_edge,num_key,key[300][101];
char kind[101];

void insert_edge(int x,int y)
{
	len_edge++;
	edge[len_edge].aim=y;
	edge[len_edge].last=pl[x];
	pl[x]=len_edge;
}

void init(int o,string z)
{
	int p,i,num;
	string t;
	p=1;
	z+=' ';
	for(i=1;i<z.length();i++)
		if(z[i]==' ')
		{
			t=z.substr(p,i-p);
			if(t[0]=='i')
				num=0;
			else
				num=n;
			if(t.length()==2)
				num+=t[1]-'0';
			else
			{
				num+=(t[1]-'0')*10+t[2]-'0';
			}
			coun[o]++;
			insert_edge(num,o);
			p=i+1;
		}
}

bool solve(int key[],int poi,int sta)
{
	int i,p,o,w,tmp,que[101],f[101];
	for(i=1;i<=n+m+k;i++)
	{
		f[i]=0;
	}
	for(i=1;i<=n;i++)
		f[i]=key[i];
	for(i=1;i<=m;i++)
	{
		if(kind[i]=='a')
			f[i+n]=1;
		else
			f[i+n]=0;
	}
	o=n;w=0;
	for(i=1;i<=n;i++)
		que[i]=i;
	while(w<o)
	{
		w++;
		if(que[w]==poi)
		{
			if(sta==2)
				f[que[w]]=!f[que[w]];
			else
				f[que[w]]=sta;
		}
		p=pl[que[w]];
		while(p!=-1)
		{
			coun[edge[p].aim]--;
			if(coun[edge[p].aim]==0)
			{
				que[++o]=edge[p].aim;
			}
			tmp=edge[p].aim;
			if(kind[tmp-n]=='a')
			{
				if(f[que[w]]==0)
					f[tmp]=0;
			}
			else if(kind[tmp-n]=='o')
			{
				if(f[que[w]]==1)
					f[tmp]=1;
			}
			else if(kind[tmp-n]=='x')
			{
				f[tmp]=f[tmp]^f[que[w]];
			}
			else
			{
				f[tmp]=!f[que[w]];
			}
			p=edge[p].last;
		}
	}
	for(i=1;i<=n+m+k;i++)
		coun[i]=tmp_coun[i];
	for(i=1;i<=k;i++)
	{
		if(f[inde[i]+n]!=key[n+i])
			return false;
	}
	return true;
}

void work(int t)
{
	int i,j,p,ans1,ans2,coun_ans;
	bool ok=true;
	for(i=1;i<=num_key;i++)
	{
		if(!solve(key[i],-1,-1))
		{
			ok=false;
			break;
		}
	}
	if(ok)
	{
		cout<<"Case "<<t<<": No faults detected\n";
		return;
	}
	ans1=ans2=coun_ans=0;
	for(i=1;i<=m;i++)
	{
		for(j=0;j<=2;j++)
		{
			ok=true;
			for(p=1;p<=num_key;p++)
			{
				ok=solve(key[p],i+n,j);
				if(!ok)
					break;
			}
			if(ok)
			{
				ans1=i;
				ans2=j;
				coun_ans++;
			}
		}
	}
	if(coun_ans!=1)
	{
		cout<<"Case "<<t<<": Unable to totally classify the failure\n";
		return;
	}
	if(ans2==2)
	{
		cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output inverted\n";
		return;
	}
	if(ans2==0)
	{
		cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output stuck at 0\n";
		return;
	}
	if(ans2==1)
	{
		cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output stuck at 1\n";
		return;
	}
}

int main()
{
	int t,i,j;
	string z;
	t=0;
	while(cin>>n>>m>>k && n+m+k!=0)
	{
		t++;
		memset(coun,0,sizeof(coun));
		len_edge=-1;
		for(i=1;i<=n+m+k;i++)
			pl[i]=-1;
		for(i=1;i<=m;i++)
		{
			cin>>kind[i];
			getline(cin,z);
			init(i+n,z);
		}
		for(i=1;i<=n+m+k;i++)
			tmp_coun[i]=coun[i];
		for(i=1;i<=k;i++)
			cin>>inde[i];
		cin>>num_key;
		for(i=1;i<=num_key;i++)
			for(j=1;j<=n+k;j++)
				cin>>key[i][j];
		work(t);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值