My Bad(暴力)をトレーニングするBlue Bridge CupアルゴリズムのJava実装

テスト質問アルゴリズムのトレーニング

問題の説明
  論理回路は、その入力を別のゲートを介して出力にマップし、回路にはループがありません。入力と出力は、1と0として表される順序付けられた論理値のセットです。私たちが検討している回路は、ANDゲート(両方の入力が1の場合、出力は1のみです)またはORゲート(または、2つの入力の1つが1である限り、出力は1です)で構成されます。 XORゲート(排他的または(xor)ゲート、2つの入力の1つだけが1、出力は1)であり、ゲートではありません(ゲートではなく、単一値入力、出力は入力の補数です)。次の図は、2つの回路を示しています。
ここに画像の説明を挿入
  残念ながら、実際にはドアが壊れることがあります。フォルトはさまざまな方法で発生する可能性がありますが、この質問は、ドアに発生する可能性のあるフォルトを次の3つの形式のいずれかに制限します
  。1)常に正しい出力とは反対;
  2)常に0を生成する;
  3)常に1を生成する;
  この質問で与えられた回路では、多くても1つのドアだけが故障します。
  回路を分析するプログラムを作成し、複数の入力と出力のセットを試して、回路が正しく動作しているか、正しく動作していないかを確認してください。少なくとも1セットの入力が誤った出力を生成する場合、プログラムは、失敗した唯一のドアと、ドアの故障方法を判別する必要があります。しかし、それは判断することも不可能かもしれません。
入力フォーマット
  入力は複数のテストデータセットで構成され、各テストケースセットは回路とその入出力を記述します。各テストデータは、次の部分を順番に示します。
  1. 1行に3つの正の整数が示されます。回路の入力数(N≤8)、ゲート数(G≤19)、出力数(U≤19)です。
  2. 1行に1つのゲート、最初の行はg1ゲートを表し、複数のゲートがある場合、次の行はg2ゲートを表します。各行は、ゲートタイプ(a =および、n =ない、o =または、x =排他的OR)およびこのゲートへのすべての入力の識別子を示します。このゲートへの入力は、回路入力(i1、i2、…)または別のゲートからの出力(g1、g2、…)。
  3. 1つの行は、U出力u1、u2、…に関連付けられたゲートの番号を示します。たとえば、g5からのu1、g1からのu2、g4からのu3の3つの出力がある場合、この動作は5 1 4。
  4. 1行で整数が示され、回路の実験数(B)が示されます。
  5.最後に、各行に(N + U)の値(1と0)、および実験の入力値と対応する出力値を含む行Bが与えられます。2つの同一の入力がある場合はありません。
  入力の識別子または数値はスペースで区切られ、入力は3つの0を含む行で終わります。
出力形式
  入力データ内の各回路について、テストデータ番号(1から開始)を出力し、次にコロンとスペースを出力してから、回路解析を出力します。内容は次のいずれかです(#を使用して対応するゲート番号を置き換えます)。 :

障害は検出されませんでした
  ゲート#の障害、出力反転
  ゲート#の障害、出力が0でスタック
  ゲート#の障害、出力が1でスタック
  障害を完全に分類できない
  図1と図2の回路図は最初のものです最後のテストデータ。

样例输入
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元の記事 ウォンの賞賛30000 + ビュー449万+

おすすめ

転載: blog.csdn.net/a1439775520/article/details/105488761