Description

Have you ever thought about comparing the weight of fruits? That’s what you should do in this problem! Given a series of fruit weight comparisons, you should anticipate the result of another comparison. In this problem, all fruits of the same kind are identical and have the same weights. Each fruit weight comparison is something like “a X ≤ b Y” in which a and b are positive integers, and X and Y are fruit names. Such a comparison means that the weight of a fruits of type X is less than or equal to the weight of b fruits of type Y.

Input

The input contains multiple test cases. Each test case starts with a line containing n, which is the number of given comparisons. Each of the next n lines gives a comparison in the form of “a X b Y” meaning that “a X ≤ b Y”. The last line of each test case contains the comparison query in the same form of “a X b Y” inquiring the comparison of “a X” and “b Y”. 
A case of n = 0 shows the end of input and should not be processed. All integers in the input (except the last n which is 0) are positive and are not greater than 100. Fruit names are case-sensitive strings of (lowercase and uppercase) letters with length no more than 50.

Output

For each test case, write one line with your result for that test case. Your result can be one of the followings (assume the comparison query was “a X b Y”):  “<=”: meaning you are sure that “a X ≤ b Y”.  “>=”: meaning you are sure that “a X ≥ b Y”.  “==”: meaning you are sure that “a X = b Y” (i.e. you have reached both of the above results).  “UNAVAILABLE”: meaning that you can say nothing for sure in comparing “a X” and “b Y” (i.e. you have reached none of the above results).  “INCONSISTENT”: meaning that there is an inconsistency in the given comparisons (i.e. you are sure that all the given comparisons for that test case cannot hold at the same time).

题目大意:给n条aX ≤ bY的不等式,其中X、Y是未知数的符号,a、b是常数。最后给出aX ? bY,要求判断 ? 是哪个符号。如果相等输出==,大于等于输出>=,小于等于输出<=,不能判断输出UNAVAILABLE,n条不等式不可能同时成立输出INCONSISTENT。

思路:首先X、Y是各种各样的字符串,所以先离散化,C++里面的map<string, int>是不错的选择。然后我们就要考虑,不同的不等式,该怎样才能联立起来。比如2a ≤ 3b,5b ≤ 7c,这样就会确定了一个关于a和c的不等式,然而我们须要表现在代码里面,不是很容易做到。

所以移向,2/3 a ≤ b, 5/7 b ≤ c,如果 c 到 b 连一条边,权值为 5/7; b 到 a 连一条边,权值为 2/3。那么,我们从 c 走到 a,就可以得到 (5/7 * 2/3) * a ≤ c。如果有假设提问是x * a ? y * c,那么对所有x/y ≤ (5/7 * 2/3),因为若p ≤ q,有pa ≤ qa ≤ qc。

然后对每一条边,取最大的权值。因为若有两条边pa ≤ pc,qa ≤ qc,且p ≤ q,那么我们只要保留qa ≤ qc,那么我们就可以推断出pa ≤ pc。

根据上述推论,我们用floyd来直接求出最长路径,mat[j][i]代表mat[j][i] * i ≤ j。n个不等式冲突,就说明存在mat[i][i] > 1,令mat[i][i] * i ≤ i无法成立,输出INCONSISTENT。对询问x * i ? y * j,若有y/x = mat[i][j]且x/y = mat[j][i],那么有x * i = y * j。若有y/x ≤ mat[i][j],则有x * i ≥ y * j。若 x/y ≤ mat[j][i],则有x * i ≤ y * j。若前面都不成立,则说明无法判断,输出UNAVAILABLE。

对于询问x * i ? y * j, i 或 j 前面都没有出现过的,好像是没有这种情况,别人没管这个也能AC。

PS:之前闲得无聊写了一个分数类结果RE了,大概是乘起来太大然后求约数的时候被零除跪了,好吧这不是重点。

PS2:最短路径的那个代码就是把原来的mat[j][i] * i ≤ j换成了i ≤ j * mat[j][i],思路差不多。

代码(125MS)(最长路径):

 #include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; map<string, int> mp;
string a, b;
int m, n; double x, y;
int aid, bid;
double mat[MAXN][MAXN]; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} bool floyd() {
for(int k = ; k <= n; ++k)
for(int i = ; i <= n; ++i) if(mat[i][k] > )
for(int j = ; j <= n; ++j) if(mat[k][j] > )
if(mat[i][k] * mat[k][j] > mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];
/*
for(int k = 1; k <= n; ++k)
for(int i = 1; i <= n; ++i) if(mat[i][k] > 0)
for(int j = 1; j <= n; ++j) if(mat[k][j] > 0)
if(mat[i][j] > 0 && sgn(mat[i][k] * mat[k][j] - mat[i][j]) == 1) return false;*/
for(int i = ; i <= n; ++i)
for(int j = i + ; j <= n; ++j) {
if(mat[i][j] < || mat[j][i] < ) continue;
if(mat[i][j] * mat[j][i] > ) return false;
}
return true;
} int main() {
ios::sync_with_stdio(false);
while(cin>>m) {
if(m == ) break;
n = ;
mp.clear();
for(int i = ; i < MAXN; ++i) {
for(int j = ; j < MAXN; ++j) mat[i][j] = -;
mat[i][i] = ;
}
for(int i = ; i < m; ++i) {
cin>>x>>a>>y>>b;
if(mp.find(a) != mp.end()) aid = mp[a];
else mp[a] = aid = ++n;
if(mp.find(b) != mp.end()) bid = mp[b];
else mp[b] = bid = ++n;
//if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);
if(mat[bid][aid] < x / y) mat[bid][aid] = x / y;
}
cin>>x>>a>>y>>b;
if(!floyd()) {
puts("INCONSISTENT");
continue;
}
if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {
puts("UNAVAILABLE");
continue;
}
aid = mp[a];
bid = mp[b];
if(sgn(mat[aid][bid] - y / x) == && sgn(mat[bid][aid] - x / y) == ) {
puts("==");
continue;
}
if(mat[bid][aid] > && sgn(mat[bid][aid] - x / y) >= ) {
puts("<=");
continue;
}
if(mat[aid][bid] > && sgn(mat[aid][bid] - y / x) >= ) {
puts(">=");
continue;
}
puts("UNAVAILABLE");
}
}

代码(125MS)(最短路径):

 #include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; map<string, int> mp;
string a, b;
int m, n; double x, y;
int aid, bid;
double mat[MAXN][MAXN]; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} bool floyd() {
for(int k = ; k <= n; ++k)
for(int i = ; i <= n; ++i) if(mat[i][k] > )
for(int j = ; j <= n; ++j) if(mat[k][j] > )
if(mat[i][j] < || mat[i][k] * mat[k][j] < mat[i][j]) mat[i][j] = mat[i][k] * mat[k][j];
for(int i = ; i <= n; ++i)
for(int j = i + ; j <= n; ++j) {
if(mat[i][j] < || mat[j][i] < ) continue;
if(sgn(mat[i][j] * mat[j][i] - ) < ) return false;
}
return true;
} int main() {
ios::sync_with_stdio(false);
while(cin>>m) {
if(m == ) break;
n = ;
mp.clear();
for(int i = ; i < MAXN; ++i) {
for(int j = ; j < MAXN; ++j) mat[i][j] = -;
mat[i][i] = ;
}
for(int i = ; i < m; ++i) {
cin>>x>>a>>y>>b;
if(mp.find(a) != mp.end()) aid = mp[a];
else mp[a] = aid = ++n;
if(mp.find(b) != mp.end()) bid = mp[b];
else mp[b] = bid = ++n;
if(aid == bid) continue;
//if(mat[aid][bid] < double(x, y)) mat[aid][bid] = double(x, y);
if(mat[bid][aid] < || mat[bid][aid] > y / x) mat[bid][aid] = y / x;
}
cin>>x>>a>>y>>b;
if(!floyd()) {
puts("INCONSISTENT");
continue;
}
if(mp.find(a) == mp.end() || mp.find(b) == mp.end()) {
puts("UNAVAILABLE");
continue;
}
aid = mp[a];
bid = mp[b];
if(sgn(mat[aid][bid] - x / y) == && sgn(mat[bid][aid] - y / x) == ) {
puts("==");
continue;
}
if(mat[bid][aid] > && sgn(mat[bid][aid] - y / x) <= ) {
puts("<=");
continue;
}
if(mat[aid][bid] > && sgn(mat[aid][bid] - x / y) <= ) {
puts(">=");
continue;
}
puts("UNAVAILABLE");
}
}

POJ 3860 Fruit Weights(数学+最长路径 or 最短路径)的更多相关文章

  1. POJ 1797 Heavy Transportation(Dijkstra变形——最长路径最小权值)

    题目链接: http://poj.org/problem?id=1797 Background Hugo Heavy is happy. After the breakdown of the Carg ...

  2. 【POJ 3162】 Walking Race (树形DP-求树上最长路径问题,+单调队列)

    Walking Race   Description flymouse's sister wc is very capable at sports and her favorite event is ...

  3. Going from u to v or from v to u? POJ - 2762(强连通 有向最长路径)

    In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, an ...

  4. ubuntu 终端设置(颜色与长路径)

    Linux给人最大的享受就是可以根据个人喜好去定制令自己舒服的系统配置,像终端颜色的设置就是一个典型的例子. 图1 系统默认状态下的终端显示     在没有经过自定义配置的终端下工作久了,难免容易疲劳 ...

  5. Codefroces Gym 100781A(树上最长路径)

    http://codeforces.com/gym/100781/attachments 题意:有N个点,M条边,问对两两之间的树添加一条边之后,让整棵大树最远的点对之间的距离最近,问这个最近距离是多 ...

  6. poj 2533 Longest Ordered Subsequence 最长递增子序列

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098562.html 题目链接:poj 2533 Longest Ordered Subse ...

  7. hdoj 2196 Computer【树的直径求所有的以任意节点为起点的一个最长路径】

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. AOE网上的关键路径(最长路径 + 打印路径)

    题目描述 一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图.     AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG ...

  9. HDU 1069 Monkey and Banana / ZOJ 1093 Monkey and Banana (最长路径)

    HDU 1069 Monkey and Banana / ZOJ 1093 Monkey and Banana (最长路径) Description A group of researchers ar ...

随机推荐

  1. ContentProvider 、 ContentResolver 、 ContentObserver

    说说ContentProvider . ContentResolver . ContentObserver 之间的关系**a. ContentProvider 内容提供者,用于对外提供数据 b. Co ...

  2. java基础(杂记)

    java基础夯实(杂记):1:创建实例对象可以通过无参的构造函数然后调用成员变量去初始化属性,也可以自己定义有参构造方法直接初始化属性,当属性为private时我们可以通过getset方法间接访问:2 ...

  3. 分享一个带有合计行功能的DataGridView扩展

    因为一个Winform的项目中需要用到带有合计行的表格,并且需要满足以下需求: 合计行可自动对需要求和的列进行求和计算; 合计行必须固定(冻结)在表格的最底部,且其位置不受滚动条的滚动而移动; 可以设 ...

  4. [Oracle]分区索引

    上一节学习了分区表,接着学习分区索引. (一)什么时候对索引进行分区 · 为了避免移动数据时重建整个索引,可对索引分区,在重建索引时,只需重建与数据分区相关的索引: · 在对分区表进行维护时,为了避免 ...

  5. 不再手写import - VSCode自动引入Vue组件和Js模块

    :first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...

  6. 替换html里面的\r\n及解决记事本中的每个段落只有一行的情形

    1. 在用python爬取小说的时候, 发现在内容里每次换行都有\r\n(即回车, 换行)出现. 此时可以采用  s.replace('\\r\\n','') , 其中s为字符串类型. 2. 在爬取完 ...

  7. 安装Chrome插件

    重装系统后重装了Chrome浏览器,想着将自己的东西同步到Chrome上.但是登录谷歌账号要FQ,我又是靠setup插件FQ,但插件又要靠账号同步到本地.形成了死循环. 其实重装系统前我将插件提取了, ...

  8. [tree]合并果子(哈夫曼树+优先队列)

    现在有n堆果子,第i堆有ai个果子.现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数.求合并所有果子的最小代价. Input 第一行包含一个整数T(T<=50),表示数据组数. 每 ...

  9. substr在oracle和mysql中的应用和区别

    Oracle: 书写格式: (1)Select  substr(字段名(string) , 起始位置(int) , 截取长度(int)) 示例: selectsubstr('123456',0,3)a ...

  10. [NodeJs系列][译]理解NodeJs中的Event Loop、Timers以及process.nextTick()

    译者注: 为什么要翻译?其实在翻译这篇文章前,笔者有Google了一下中文翻译,看的不是很明白,所以才有自己翻译的打算,当然能力有限,文中或有错漏,欢迎指正. 文末会有几个小问题,大家不妨一起思考一下 ...