Implementación en Java del entrenamiento del algoritmo Blue Bridge Cup My Bad (violento)

Test Algoritmo de preguntas Entrenamiento My Bad

Descripción del problema
  Un circuito lógico asigna su entrada a la salida a través de diferentes puertas, y no hay un bucle en el circuito. La entrada y la salida son un conjunto ordenado de valores lógicos, que se representan como 1s y 0s. El circuito que estamos considerando consiste en una compuerta AND (la salida es solo 1 cuando ambas entradas son 1), o una compuerta OR (o compuerta, siempre que una de las dos entradas sea 1, la salida es 1), Puerta XOR (puerta exclusiva o (xor), solo una de las dos entradas es 1, la salida es 1) y no puerta (no puerta, entrada de valor único, la salida es el complemento de la entrada). La siguiente figura muestra dos circuitos.
Inserte la descripción de la imagen aquí
  Desafortunadamente, en la práctica, la puerta a veces falla. Aunque las fallas pueden ocurrir de muchas maneras diferentes, esta pregunta limita las fallas que pueden ocurrir a la puerta a una de las siguientes tres formas:
  1) siempre opuesta a la salida correcta;
  2) siempre produce 0;
  3) siempre produce 1;
  En el circuito dado en esta pregunta, como máximo solo una puerta falla.
  Escriba un programa para analizar un circuito y experimente con múltiples conjuntos de entradas y salidas para ver si el circuito funciona de manera correcta o incorrecta. Si al menos un conjunto de entradas produce una salida errónea, el programa debe determinar la única puerta que falló y la forma en que la puerta falló. Pero también puede ser imposible juzgar.
La entrada del formato de
  entrada consta de múltiples conjuntos de datos de prueba, cada conjunto de casos de prueba describe un circuito y su entrada y salida. Cada dato de prueba da las siguientes partes en orden.
  1. Se proporcionan tres enteros positivos en una línea: el número de entradas en el circuito (N ≤ 8), el número de puertas (G ≤ 19) y el número de salidas (U ≤ 19).
  2. Una puerta por línea, la primera línea describe la puerta g1, si hay varias puertas, la siguiente línea describe la puerta g2, y así sucesivamente. Cada línea proporciona el tipo de puerta (a = y, n = no, o = o, x = exclusivo o) y el identificador de todas las entradas a esta puerta. La entrada a esta puerta proviene de la entrada del circuito (i1, i2, ...) o La salida de otra puerta (g1, g2, ...).
  3. Una línea da el número de la puerta asociada con las salidas U u1, u2,…. Por ejemplo, si hay tres salidas, u1 de g5, u2 de g1, u3 de g4, entonces este comportamiento: 5 1 4.
  4. Una línea da un número entero, que indica el número de experimentos (B) en el circuito.
  5. Finalmente, se proporciona la línea B, con valores (N + U) (1 y 0) en cada línea, y se proporcionan el valor de entrada y el valor de salida correspondiente del experimento. No hay ningún caso en el que haya dos entradas idénticas.
  Los identificadores o números en la entrada están separados por espacios, y la entrada termina con una línea que contiene 3 0s.
Formato de salida
  Para cada circuito en los datos de entrada, envíe el número de datos de prueba (comenzando desde 1), luego envíe dos puntos y un espacio, y luego envíe el análisis del circuito, el contenido es uno de los siguientes (use # para reemplazar el número de puerta correspondiente) :

Fallos detectados NO
  Puerta # es el fallando; salida invertida
  Puerta # es el fallando; 0 Salida Stuck AT
  Puerta # es el defecto, y la salida atascado en 1
  Incapaz para clasificar Totalmente El fracaso
  .. Diagrama de circuito dado en la figura 1 y la figura 2 es una primera y Los últimos datos de prueba.

样例输入
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 artículos originales publicados · 30,000 Me gusta + · 4.49 millones de visitas

Supongo que te gusta

Origin blog.csdn.net/a1439775520/article/details/105488761
Recomendado
Clasificación