Java implementation of Blue Bridge Cup algorithm training My Bad (violent)

Test Question Algorithm Training My Bad

Problem description
  A logic circuit maps its input to output through different gates, and there is no loop in the circuit. Input and output are an ordered set of logical values, which are represented as 1s and 0s. The circuit we are considering consists of an AND gate (the output is only 1 when both inputs are 1), or an OR gate (or gate, as long as one of the two inputs is 1, the output is 1), XOR gate (exclusive or (xor) gate, only one of the two inputs is 1, the output is 1) and not gate (not gate, single value input, output is the complement of the input). The following figure shows two circuits.
Insert picture description here
  Unfortunately, in practice, the door sometimes fails. Although faults can occur in many different ways, this question limits the faults that can occur to the door to one of the following three forms:
  1) always opposite to the correct output;
  2) always produces 0;
  3) always produces 1;
  In the circuit given in this question, at most only one door fails.
  Please write a program to analyze a circuit and experiment with multiple sets of inputs and outputs to see if the circuit is operating correctly or incorrectly. If at least one set of inputs produces an erroneous output, the program must determine the only door that failed and the way the door failed. But it may also be impossible to judge.
Input format
  input consists of multiple sets of test data, each set of test cases describes a circuit and its input and output. Each test data gives the following parts in order.
  1. Three positive integers are given on one line: the number of inputs in the circuit (N ≤ 8), the number of gates (G ≤ 19) and the number of outputs (U ≤ 19).
  2. One gate per line, the first line describes g1 gate, if there are several gates, the next line describes g2 gate, and so on. Each line gives the gate type (a = and, n = not, o = or, x = exclusive or) and the identifier of all inputs to this gate. The input to this gate comes from the circuit input (i1, i2,…) or The output from another gate (g1, g2,…).
  3. One line gives the number of the gate associated with the U outputs u1, u2,…. For example, if there are three outputs, u1 from g5, u2 from g1, u3 from g4, then this behavior: 5 1 4.
  4. One line gives an integer, indicating the number of experiments (B) on the circuit.
  5. Finally, line B is given, with (N + U) values ​​(1 and 0) in each line, and the input value and corresponding output value of the experiment are given. There is no case where there are two identical inputs.
  The identifiers or numbers in the input are separated by spaces, and the input ends with a line containing 3 0s.
Output format
  For each circuit in the input data, output the test data number (starting from 1), then output a colon and a space, and then output the circuit analysis, the content is one of the following (use # to replace the corresponding 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 circuit diagrams given in Figures 1 and 2 are the first and The last test data.

样例输入
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
样例输出
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
数据规模和约定
  N<=8;G,U<=19
 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main { 
	public static void main(String[] args) throws IOException {  
	// 转自:	https://blog.csdn.net/a1439775520  
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tokenizer = new StringTokenizer("");
		int kk = 0;
		while (true) {
			tokenizer = new StringTokenizer(reader.readLine());
			int in = Integer.parseInt(tokenizer.nextToken());
			int door = Integer.parseInt(tokenizer.nextToken());
			int out = Integer.parseInt(tokenizer.nextToken());
			if (in == 0 && door == 0 && out == 0)
				break;
			kk++;
			System.out.printf("Case %d: ", kk);
			Door d[] = new Door[20];
			for (int i = 1; i <= door; i++) {
				tokenizer = new StringTokenizer(reader.readLine());
				String kind = tokenizer.nextToken();
				int incont = 2;
				if (kind.equals("n"))
					incont = 1;
				int kinda = -1;
				if (kind.equals("a"))
					kinda = 1;
				else if (kind.equals("o"))
					kinda = 2;
				else if (kind.equals("x"))
					kinda = 3;
				else if (kind.equals("n"))
					kinda = 4;
				String aa = tokenizer.nextToken();
				int ina = Integer.parseInt(aa.substring(1));
				// System.out.println("ina :" + ina);
				if (aa.charAt(0) == 'i')
					ina = -ina;
				int inb = 0;
				if (incont == 2) {
					String bb = tokenizer.nextToken();
					inb = Integer.parseInt(bb.substring(1));
					// System.out.println("inb :" + inb);
					if (bb.charAt(0) == 'i')
						inb = -inb;
				}
				d[i] = new Door(i, kinda, ina, inb);
			}
			boolean[] visit = new boolean[60];
			for (int i = 0; i <= 3 * door; i++)
				visit[i] = true;
			int[] s = new int[20];
			int[] o = new int[20];
			int conts = 0;
			for (int i = 1; i <= door; i++) {
				int inta = d[i].ina;
				int intb = d[i].inb;
				if (inta > 0)
					d[inta].addout(i);
				if (intb > 0)
					d[intb].addout(i);
				if (inta <= 0 && intb <= 0)
					s[conts++] = i;
			}
			tokenizer = new StringTokenizer(reader.readLine());
			for (int i = 0; i < out; i++)
				o[i] = Integer.parseInt(tokenizer.nextToken());
			int test = Integer.parseInt(reader.readLine());
			int[] ins = new int[10];
			String outs = "";
			String res = "";
			for (int i = 0; i < test; i++) {
				tokenizer = new StringTokenizer(reader.readLine());
				for (int j = 1; j <= in; j++)
					ins[j] = Integer.parseInt(tokenizer.nextToken());
				outs = "";
				for (int j = 0; j < out; j++)
					outs += tokenizer.nextToken();
				for (int cas = 0; cas <= 3 * door; cas++) {
					if (visit[cas]) {
						for (int j = 1; j <= door; j++)
							d[j].cont = d[j].have = 0;
						for (int j = 0; j < conts; j++) {
							int id = s[j];
							d[id].cal(ins, d, cas);
						}
						res = "";
						for (int j = 0; j < out; j++)
							res += String.valueOf(d[o[j]].value);
						if (outs.equals(res) == false)
							visit[cas] = false;
					}
				}
			}
			if(visit[0] == true)
				System.out.println("No faults detected");
			else {
				int one = -1;
				boolean mark = true;
				for(int i = 0; i<=3*door; i++) {
					if(visit[i] == true)
					{
						if(one == -1)
							one = i;
						else
						{
							mark = false;
							break;
						}
					}
				}
				if(mark) {
					int id = (one-1)/3 + 1;
					int r = one%3;
					if(r == 0)
						r+=3;
					if(r == 1)
						System.out.printf("Gate %d is failing; output inverted\n", id);
					else if(r == 2)
						System.out.printf("Gate %d is failing; output stuck at 0\n", id);
					else if(r == 3)
						System.out.printf("Gate %d is failing; output stuck at 1\n", id);
				}
				else
					System.out.println("Unable to totally classify the failure");
			}
		}
	}
}

class Door {
	int id;
	int incont;
	int cont;
	int ina, inb;
	int kind;
	int outcont;
	int va, vb, value;
	int[] out = new int[20];
	int have;

	public Door(int id_, int kind_, int ina_, int inb_) {
		id = id_;
		kind = kind_;
		ina = ina_;
		inb = inb_;
		incont = 0;
		if (ina > 0)
			incont++;
		if (inb > 0)
			incont++;
		outcont = cont = have = 0;
	}

	public void addout(int num) {
		out[outcont++] = num;
	}

	public void cal(int[] ins, Door[] d, int cas) {
		if (ina < 0)
			va = ins[-ina];
		else if (ina > 0)
			va = d[ina].value;
		if (inb < 0)
			vb = ins[-inb];
		else if (inb > 0)
			vb = d[inb].value;
		if (kind == 1)
			value = va & vb;
		else if (kind == 2)
			value = va | vb;
		else if (kind == 3)
			value = va ^ vb;
		else if (kind == 4)
			value = va == 0 ? 1 : 0;
		if (cas != 0 && (cas - 1) / 3 + 1 == id) {
			int r = cas % 3;
			if (r == 0)
				r = 3;
			if (r == 1)
				value = value == 0 ? 1 : 0;
			else if (r == 2)
				value = 0;
			else if (r == 3)
				value = 1;
		}
		update(ins, d, cas);
	}

	public void update(int[] ins, Door[] d, int r) {
		for (int i = 0; i < outcont; i++) {
			d[out[i]].cont++;
			if (d[out[i]].cont == d[out[i]].incont) {
				d[out[i]].cal(ins, d, r);
			}
		}
	}
}

1794 original articles published · 30,000 likes + · 4.49 million views

Guess you like

Origin blog.csdn.net/a1439775520/article/details/105488761