2016"百度之星" - 资格赛(Astar Round1)Problem E(复杂模拟题)

Problem E

 
 
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
Problem Description

小度熊是一个尽职尽责的程序熊,每天产出数千行的代码,代码当中存在很多判断条件。度熊想让自己代码中的这些条件不存在交集。为了简化问题,一个条件可以是一个『简单条件』或者是一个『复合条件』,简单条件由『变量』、『比较符』和『运算数』组成,其中『变量』是用小写字符表示的一串字符,『运算数』仅为整数,『运算符』包括:<、>、<=、>=、==。分别代表:小于、大于、小于等于、大于等于和等于关系。简单条件的格式固定,左边为变量名,中间为操作符,右边为数字。若干个『简单条件』中间通过英文逗号组成一个『复合条件』,各『简单条件』之间是逻辑与的关系,例如:

简单条件: a > 100

复合条件: duxiong < 1000 , a > 100

Input

这里包括一组测试数据,第一行一个正整数 N(1 \leq N \leq 1000)N(1N1000),接下来 NN 行,每行一个条件,条件可能是一个『简单条件』或者是一个『复合条件』。其中『变量』不会超过30个字符,『运算数』的绝对值在10,000以内。测试数据中,不同变量的数量不会超过30个。其中『变量』、『比较符』和『运算数』 之前和之后都有可能出现若干空格字符。所有简单规则都是按照『变量』『比较符』『运算数』这样的顺序定义的,没有特例。

Output

对于第 ii 个条件,输出其与前 i-1i1个条件是否存在交集非空的情况。如果不存在交集非空的其他条件,输出一行字符串:『unique』。否则按照从小到大的顺序输出与其存在非空交集的条件的编号,编号之间用空格分隔,最后一个编号末尾不加空格。各条件从1-N1N编号。

Sample Input
4
a < 100
c > 99
b > 100 , b == 99 , c < 98
a < 1000, a >= 99
Sample Output
unique
1
unique
1 2
解题思路:其实这道题没什么特别可以讲的地方,因为它的思路很简单,就是模拟

可能一开始不太能理解它的样例,不清楚为什么第二个条件c>99第一个条件a<100会有交集

原因很简单,第二个条件只规定了c的下限,而没有规定a的范围,故而默认a是可以任意取的,而第一个条件a<100,所以小于100的数是可以任意取的,故而存在交集

而需要注意的大概有这么几点:

①对于一个复合条件,多个条件若矛盾,就意味着该复合条件是个空集,那与其它条件必定是没有交集的,即"unique"

②两个条件之间有交集,当且仅当两个条件里的所有变量分别都有交集才算两个条件之间有交集

因为最多总共就30个变量,故我们可以开辟一个s[1000][30][2]的数组,第一维表示条件,第二维表示变量,第三维表示变量的上下界,然后处理输入的字符串之后再进行比较即可

题目链接→HDU 5689 Problem E

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
int a[1007][37][2];
bool f[1007];
map<string,int> mp;
int n;
char str[1000010],op[3];
string s1;
int main()
{
    int i,j,k,cnt,pos,flag;
    int val;
    while(~scanf("%d",&n))
    {
        mp.clear();
        cnt = 0;
        getchar();
        for(i = 0;i < n;i++)
        {
            for(j = 1;j <= 30;j++)
            {
                a[i][j][0] = -1000001;
                a[i][j][1] =  1000001;

            }f[i] = true;
            memset(str,0,sizeof(str));
            gets(str);
            for(j = 0;str[j];j++)
            {
                if(str[j] == ' ' || str[j] == ',') continue;
                s1 = "";
                while(str[j] >= 'a' && str[j] <= 'z')
                    s1 += str[j++];
                if(mp[s1] == 0)
                    mp[s1] = ++cnt;
                pos = mp[s1];
                while(str[j] == ' ') j++;
                memset(op,0,sizeof(op));
                op[0] = str[j];
                if(str[++j] == '=')
                {
                    op[1] = str[j++];
                    op[2] = '\0';
                }
                else
                    op[1] = '\0';
                while(str[j] == ' ') j++;
                val = 0;
                while(str[j] && str[j] >= '0' && str[j] <= '9')
                    val = val*10 + str[j++] - '0';
              //  cout<<"_____"<<s1<<" "<<pos<<" "<<op<<" "<<val<<"_____"<<endl;
                // a[i][pos][0] a[i][pos][1]op val
                if(op[0] == '>' && op[1] == '\0')
                {
                    if(val >= a[i][pos][1]) f[i] = false;
                    else if(val >= a[i][pos][0]) a[i][pos][0] = val+1;
                }
                else if(op[0] == '<' && op[1] == '\0')
                {
                    if(val <= a[i][pos][0]) f[i] = false;
                    else if(val <= a[i][pos][1]) a[i][pos][1] = val-1;
                }
                else if(op[0] == '>' && op[1] == '=')
                {
                    if(val > a[i][pos][1]) f[i] = false;
                    else if(val > a[i][pos][0]) a[i][pos][0] = val;
                }
                else if(op[0] == '<' && op[1] == '=')
                {
                    if(val < a[i][pos][0]) f[i] = false;
                    else if(val < a[i][pos][1]) a[i][pos][1] = val;
                }
                else if(op[0] == '=')
                {
                    if(!(val >= a[i][pos][0] && val <= a[i][pos][1]))   f[i] = false;
                    else
                    {
                        a[i][pos][0] = val;
                        a[i][pos][1] = val;
                    }
                 }
               //  cout<<"_____"<<a[i][pos][0]<<" "<<a[i][pos][1]<<"_____"<<endl;
                 if(!f[i]) break;
            }
            for(j = 0,flag = 0;j < i && f[i];j++)
            {
                if(!f[j]) continue;
                for(k = 1;k <= 30;k++)
                    if(a[i][k][0] > a[j][k][1] || a[i][k][1] < a[j][k][0])
                        break;
                if(k != 31) continue;
                if(!flag)
                {
                    printf("%d",j+1);
                    flag = 1;
                }
                else printf(" %d",j+1);
            }
            if(!flag) puts("unique");
            else puts("");
         //   for(k = 1;k <= 30;k++)
              // cout<<k<<" "<<a[i][k][0]<<" "<<a[i][k][1]<<endl;
        }
    }
    return 0;
}

菜鸟成长记

你可能感兴趣的:(模拟,ACM)