![](http://ctc.qzs.qq.com/qzone/em/e136.gif)
![](http://ctc.qzs.qq.com/qzone/em/e113.gif)
题目描述:
More precisely, the format of constraints is:
token op token op ... op token
where each token is either a constant integer or a variable represented by a capital letter and each op is either less-than ( < ) or less-than-or-equal-to ( <= ).
题目大意:给定若干个由小于号(<)或者小于等于号(≤)组成的不等式表达式,表达式中可能包含变量,在给定若干组变量的赋值结果后,对于每组赋值结果判定是否所有的表达式都成立。
解答:
本题比较简单,基本没有涉及到太复杂的算法,考察的仅仅是基本的数据结构的应用和基本的编程能力。也是笔者在笔试过程中唯一做出的一道题。
基本的解题思路就是利用数据结构将各个表达式存储起来,并设计变脸索引表,存储对于变量的赋值结果。对于表达式,笔者采用链表存储。
·数据结构:
表达式的格式是:token op token op ... op token,可以选择将一个操作数(token)和一个操作符(op)作为一组,存储在一个节点中。此时一条表达式对应一个链表,同时链表的最后一个节点一定只有一个操作数。操作数的又有变量值和常数值两种,因此,设计链表节点的结构如下:
typedef struct node {
<span style="white-space:pre"> </span>int value_index; // 如果是常数值直接存储;如果是变量就保存在变量表的索引
int tag; // 标记是常数还是变量:0表示常数,1表示变量。
int op; // 操作符:1表示小于,2表示小于等于。
struct node *next; // 链指针。
} token;
本题中的变量均用一个英文大写字母表示,所以,不同的变量最多只有26个,定义一个数据存储每个变量的值即可:
int token_value[26] = {0};
·变量赋值:
变量赋值操作很简单,修改变量表中对应的值就可以了。
·计算:
计算的过程也很简单,对于每个表达式对应链表中除去最后一个节点的所有节点,取出该节点存储的操作数的值和操作符,并取出下一个节点的操作数的值,构成表达式,判定其是否正确,如果在某一个节点的计算结果为错误,那么该表达式就是错误的;如果所有节点的计算结果都是正确的,表达式就是正确的。
最后统计一下正确表达式的个数即可。
输入输出格式:
输入:
The first line contains an integer N , the number of constraints. (1 ≤ N ≤ 20)
Each of the following N lines contains a constraint in the previous mentioned format.
Then follows an integer T, the number of assignments to check. (1 ≤ T ≤ 50)
Each assignment occupies K lines where K is the number of variables in the constraints.
Each line contains a capital letter and an integer, representing a variable and its value.
It is guaranteed that:
1. Every token in the constraints is either an integer from 0 to 1000000 or an variable represented by a capital letter from 'A' to 'Z'.
2. There is no space in the constraints.
3. In each assignment every variable appears exactly once and its value is from 0 to 1000000.
输出:
For each assignment output Yes or No indicating if the constraints are satisfied.
备注:
本题还有一个问题在于题目中没有明确给出输入时每个表达式的最大长度,开始时笔者设计为100个字符,一直RE,后来改为200字符长度后就AC了。
程序代码:
/****************************************************/
/* File : HihoCoder1341 */
/* Author : Zhang Yufei */
/* Date : 2016-07-17 */
/* Description : HihoCoder ACM program. (submit:g++)*/
/****************************************************/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
/*
* Define structure record the constraint.
* Parameters:
* @value_index: If the op-num is number, record the value, or record the
* index in variable list.
* @tag: Mark the op-num is number(tag = 0) or variable (tag = 1).
* @op: The operator: value 1 means less-than (<);
* value 2 means less-than-or-equal-to (<=).
* @next: The next pointer.
*/
typedef struct node {
int value_index;
int tag;
int op;
struct node *next;
} token;
/*
* The main program.
*/
int main(void) {
int token_value[26] = {0};
int K = 0;
int N;
scanf("%d", &N);
token *cons[N];
for(int i = 0; i < N; i++) {
cons[i] = NULL;
char con[200];
scanf("%s", con);
int num = 0;
int tag = 0;
token *t;
t = NULL;
for(int j = 0; j < strlen(con); j++) {
if(isalpha(con[j])) {
if(token_value[con[j] - 65] == 0) {
token_value[con[j] - 65] = 1;
K++;
}
token *cur = (token*) malloc(sizeof(token));
cur->value_index = con[j] - 65;
cur->tag = 1;
cur->next = NULL;
if(t != NULL) {
t->next = cur;
} else {
cons[i] = cur;
}
t = cur;
} else if(isdigit(con[j])) {
tag = 1;
num *= 10;
num += con[j] - 48;
} else {
if(tag == 1) {
token *cur = (token*) malloc(sizeof(token));
cur->value_index = num;
cur->tag = 0;
cur->next = NULL;
num = 0;
if(t != NULL) {
t->next = cur;
} else {
cons[i] = cur;
}
t = cur;
tag = 0;
}
if(con[j] == '<' && con[j + 1] == '=') {
t->op = 2;
j++;
} else {
t->op = 1;
}
}
}
if(tag == 1) {
token *cur = (token*) malloc(sizeof(token));
cur->value_index = num;
cur->tag = 0;
cur->next = NULL;
num = 0;
if(t != NULL) {
t->next = cur;
} else {
cons[i] = cur;
}
t = cur;
tag = 0;
}
}
int T;
scanf("%d", &T);
for(int i = 0; i < T; i++) {
for(int j = 0; j < K; j++) {
getchar();
char var;
int value;
scanf("%c %d", &var, &value);
token_value[var - 65] = value;
}
int result = 1;
for(int j = 0; j < N; j++) {
token *t = cons[j];
while(t != NULL && t->next != NULL) {
int a, b;
if(t->tag == 0) {
a = t->value_index;
} else {
a = token_value[t->value_index];
}
if(t->next->tag == 0) {
b = t->next->value_index;
} else {
b = token_value[t->next->value_index];
}
if(t->op == 1 && a < b || t->op == 2 && a <= b) {
} else {
result = 0;
}
t = t->next;
}
if(result == 0) {
printf("No\n");
break;
}
}
if(result == 1) {
printf("Yes\n");
}
}
return 0;
}