http://codeforces.com/problemset/problem/416/A
A TV show called "Guess a number!" is gathering popularity. The whole Berland, the old and the young, are watching the show.
The rules are simple. The host thinks of an integer y and the participants guess it by asking questions to the host. There are four types of acceptable questions:
- Is it true that y is strictly larger than number x?
- Is it true that y is strictly smaller than number x?
- Is it true that y is larger than or equal to number x?
- Is it true that y is smaller than or equal to number x?
On each question the host answers truthfully, "yes" or "no".
Given the sequence of questions and answers, find any integer value of y that meets the criteria of all answers. If there isn't such value, print "Impossible".
The first line of the input contains a single integer n (1 ≤ n ≤ 10000) — the number of questions (and answers). Next n lines each contain one question and one answer to it. The format of each line is like that: "sign x answer", where the sign is:
- ">" (for the first type queries),
- "<" (for the second type queries),
- ">=" (for the third type queries),
- "<=" (for the fourth type queries).
All values of x are integer and meet the inequation - 109 ≤ x ≤ 109. The answer is an English letter "Y" (for "yes") or "N" (for "no").
Consequtive elements in lines are separated by a single space.
Print any of such integers y, that the answers to all the queries are correct. The printed number y must meet the inequation - 2·109 ≤ y ≤ 2·109. If there are many answers, print any of them. If such value doesn't exist, print word "Impossible" (without the quotes).
4 >= 1 Y < 3 N <= -3 N > 55 N
17
2 > 100 Y < -100 Y
Impossible
基本思路:首先,将区间的上下限区分出来,其次用二分搜索合适的数就可以了。
需要注意的几点:
1. 要注意上下限的开闭区间问题。例如:第六十三组数据3 >=5 <=5 <5 答案应该 是Imposible 而不是5;
2. 在搜索的时候数据的范围是-2*10^9~2*10^9 之间,如果你想用枚举,那你就废了。再者在设置二分的上下限时要比取值范围多出去一些,不要就-2*10^9~2*10^9 ,否则,这个数据你就过不了1 >= -1000000000 Y
下面是我的代码:(几经波折的代码啊,,,,)
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int n,b[10002],x,y,minn,maxn;
char a[10002][3],yy;
int dydy(int i)
{
if(a[x][1]==0&&a[y][1]==0)
return (i<minn&&i>maxn);
else if(a[x][1]==0&&a[y][1]!=0)
return (i<=minn&&i>maxn);
else if(a[x][1]!=0&&a[y][1]==0)
return (i<minn&&i>=maxn);
else if(a[x][1]!=0&&a[y][1]!=0)
return (i<=minn&&i>=maxn);
}
int main()
{
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
int flag=0;
for(int i=0;i<n;i++)
{
cin >> a[i];
cin >> b[i]>>yy;
if(yy=='N'&&a[i][0]=='>')
{
if(a[i][1]==0)
a[i][1]='=';
else if(a[i][1]!=0)
a[i][1]=0;
a[i][0]='<';
}
else if(yy=='N'&&a[i][0]=='<')
{
if(a[i][1]==0)
a[i][1]='=';
else if(a[i][1]!=0)
a[i][1]=0;
a[i][0]='>';
}
}
/* for(int i=0;i<n;i++)
printf("%s\n",a[i]);*/
minn=1e9*2+2;
maxn=-1e9*2-2;
for(int i=0;i<n;i++)
{
if(a[i][0]=='<'&&b[i]<=minn)
{
if(b[i]==minn&&a[i][1]==0)
{
y=i;
minn=b[i];
//printf("%d&&\n",maxn);
}
else if(b[i]<minn)
{
y=i;
minn=b[i];
}
}
if(a[i][0]=='>'&&b[i]>=maxn)
{
if(b[i]==maxn&&a[i][1]==0)
{
x=i;
maxn=b[i];
//printf("%d&&\n",maxn);
}
else if(b[i]>maxn)
{
x=i;
maxn=b[i];
}
}
}
// printf("(%d %d)\n",minn,maxn);
int left=-1e9*2-2;
int right=1e9*2+2;
while(left<=right)
{
int mid=(left+right)/2;
if(dydy(mid))
{
printf("%d\n",mid);
flag=1;
break;
}
else if(mid>=minn)
right=mid-1;
else if(mid<=maxn)
left=mid+1;
}
if(flag==0)
printf("Impossible\n");
}
return 0;
}
方法二:水过法:
#include <string.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
string a,b,c;
int main()
{
int n,num1=-1e9*2-1,num2=1e9*2+2,x;
while(cin >> n)
{
for(int i=0;i<n;i++)
{
cin >> a>>x>> b;
if(a==">=")
{
if(b=="Y")
num1=max(x-1,num1);
else
num2=min(x,num2);
}
else if(a=="<=")
{
if(b=="Y")
num2=min(x+1,num2);
else
num1=max(x,num1);
}
else if(a=="<")
{
if(b=="Y")
num2=min(x,num2);
else
num1=max(x-1,num1);
}
else
{
if(b=="Y")
num1=max(x,num1);
else
num2=min(x+1,num2);
}
}
//printf("%d %d\n",num1,num2);
if(num2-2<num1)//仔细想想这句话
cout << "Impossible\n";
else
cout << num1+1<< endl;
}
return 0;
}