/* Тестовая программа для задачи ZRELY http://habrahabr.ru/post/231775/ http://www.spoj.com/ZELARCH/problems/ZRELY/ */ #include #include #include #include struct node { char type; /* 0 - INPUT, 1 - WIRE, 2 - OUTPUT */ int val; /* Logic value -1 (not initialized), 0 or 1 */ char *name; /* Name of element */ struct element *fanin; /* Node can have only one input */ int oNum; struct element **fanout; /* Node can has many outputs */ }; struct element { char type; /* 1 INV 2 AND 3 OR 4 NAND 5 NOR 6 XOR */ char proc; /* For calculations (0 - not processed, 1 - processed) */ struct node *inp1; struct node *inp2; struct node *out; }; /* Global variables START */ struct node nl[100000]; int nlNum; struct element el[100000]; int elNum; struct node nl1[100000]; int nl1Num; struct element el1[100000]; int el1Num; double elemProb[6]; double elemArea[6]; double maxRedun; int inNum; int outNum; /* Global variables END */ struct node * findNode(struct node *n, int nLen, char *str) { int i; for (i = 0; i < nLen; i++) { if (!strcmp(n[i].name, str)) return &(n[i]); } return NULL; } struct node *addNode( struct node *n, int *nLen, char *str ) { n[(*nLen)].name = (char *)malloc((strlen(str) + 1)*sizeof(char)); strcpy(n[(*nLen)].name, str); n[*nLen].type = 1; n[*nLen].fanin = NULL; n[*nLen].fanout = NULL; n[*nLen].oNum = 0; (*nLen)++; return &(n[(*nLen)-1]); } void addNodeFanin( struct node *n, struct element *e) { n->fanin = e; } void addNodeFanout( struct node *n, struct element *e) { int s = n->oNum + 1; n->fanout = (struct element **)realloc(n->fanout, s*sizeof(struct element *)); n->fanout[n->oNum] = e; n->oNum++; } double findArea(struct element *e, int num) { double area = 0.0; int i, tp; for (i = 0; i < num; i++) { tp = e->type - 1; area += elemArea[tp]; } return area; } void readCircuit() { int i; char buf[128]; nlNum = 0; scanf("%lf", &maxRedun); for (i = 0; i < 6; i++) { scanf("%lf %lf", &(elemArea[i]), &(elemProb[i])); } /* Читаем схему оригинал */ scanf("%d", &inNum); for (i = 0; i < inNum; i++) { scanf("%s", buf); nl[nlNum].name = (char *)malloc((strlen(buf) + 1)*sizeof(char)); strcpy(nl[nlNum].name, buf); nl[nlNum].type = 0; nlNum++; } scanf("%d", &outNum); for (i = 0; i < outNum; i++) { scanf("%s", buf); nl[nlNum].name = (char *)malloc((strlen(buf) + 1)*sizeof(char)); strcpy(nl[nlNum].name, buf); nl[nlNum].type = 2; nlNum++; } scanf("%d", &elNum); for (i = 0; i < elNum; i++) { scanf("%s", buf); if (!strcmp(buf, "INV")) { el[i].type = 1; scanf("%s", buf); el[i].inp1 = findNode(nl, nlNum, buf); el[i].inp2 = NULL; if (el[i].inp1 == NULL) { el[i].inp1 = addNode(nl, &nlNum, buf); } addNodeFanout(el[i].inp1, &(el[i])); } else { if (!strcmp(buf, "AND")) { el[i].type = 2; } else if (!strcmp(buf, "OR")) { el[i].type = 3; } else if (!strcmp(buf, "NAND")) { el[i].type = 4; } else if (!strcmp(buf, "NOR")) { el[i].type = 5; } else if (!strcmp(buf, "XOR")) { el[i].type = 6; } scanf("%s", buf); el[i].inp1 = findNode(nl, nlNum, buf); if (el[i].inp1 == NULL) { el[i].inp1 = addNode(nl, &nlNum, buf); } addNodeFanout(el[i].inp1, &(el[i])); scanf("%s", buf); el[i].inp2 = findNode(nl, nlNum, buf); if (el[i].inp2 == NULL) { el[i].inp2 = addNode(nl, &nlNum, buf); } addNodeFanout(el[i].inp2, &(el[i])); } /* Выход схемы */ scanf("%s", buf); el[i].out = findNode(nl, nlNum, buf); if (el[i].out == NULL) { el[i].out = addNode(nl, &nlNum, buf); } addNodeFanin(el[i].out, &(el[i])); } } void freeMemory() { int i; for (i = 0; i < nlNum; i++) { free(nl[i].name); free(nl[i].fanout); nl[i].fanout = NULL; nl[i].fanin = NULL; nl[i].name = NULL; nl[i].val = -1; nl[i].oNum = 0; } for (i = 0; i < nl1Num; i++) { free(nl1[i].name); free(nl1[i].fanout); nl1[i].fanout = NULL; nl1[i].fanin = NULL; nl1[i].name = NULL; nl1[i].val = -1; nl1[i].oNum = 0; } for (i = 0; i < elNum; i++) { el[i].type = 0; el[i].proc = 0; el[i].inp1 = NULL; el[i].inp2 = NULL; el[i].out = NULL; } for (i = 0; i < el1Num; i++) { el1[i].type = 0; el1[i].proc = 0; el1[i].inp1 = NULL; el1[i].inp2 = NULL; el1[i].out = NULL; } nlNum = 0; nl1Num = 0; elNum = 0; el1Num = 0; } void solve() { // The simpliest of possible solutions: just copy the first circuit int i; for (i = 0; i < nlNum; i++) { nl1[i].name = (char *)malloc((strlen(nl[i].name) + 1)*sizeof(char)); strcpy(nl1[i].name, nl[i].name); nl1[i].type = nl[i].type; nl1[i].oNum = nl[i].oNum; nl1[i].val = 0; nl1[i].fanin = NULL; nl1[i].fanout = (struct element **)malloc(nl1[i].oNum*sizeof(struct element *)); } nl1Num = nlNum; for (i = 0; i < elNum; i++) { el1[i].type = el[i].type; el1[i].inp1 = findNode(nl1, nl1Num, el[i].inp1->name); el1[i].inp1->fanout[el1[i].inp1->val++] = &(el1[i]); if (el1[i].type == 1) { el1[i].inp2 = NULL; } else { el1[i].inp2 = findNode(nl1, nl1Num, el[i].inp2->name); el1[i].inp2->fanout[el1[i].inp2->val++] = &(el1[i]); } el1[i].out = findNode(nl1, nl1Num, el[i].out->name); el1[i].out->fanin = &(el1[i]); } for (i = 0; i < nlNum; i++) { if (nl1[i].val > nl1[i].oNum) { printf("OPA"); exit(0); } } el1Num = elNum; } void outputCircuit() { int i; printf("%d\n", el1Num); for (i = 0; i < el1Num; i++) { if (el1[i].type == 1) { printf("INV %s %s\n", el1[i].inp1->name, el1[i].out->name); } else { if (el1[i].type == 2) { printf("AND"); } else if (el1[i].type == 3) { printf("OR"); } else if (el1[i].type == 4) { printf("NAND"); } else if (el1[i].type == 5) { printf("NOR"); } else if (el1[i].type == 6) { printf("XOR"); } printf(" %s %s %s\n", el1[i].inp1->name, el1[i].inp2->name, el1[i].out->name); } } } int main() { int z; int nLen; #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); freopen("poutput.txt","w",stdout); #endif scanf("%d", &z); while(z--) { readCircuit(); solve(); outputCircuit(); freeMemory(); } return 0; }