codeforces problem/416/A 二分

http://codeforces.com/problemset/problem/416/A

A. Guess a number!
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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".

Input

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.

Output

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).

Sample test(s)
input
4
>= 1 Y
< 3 N
<= -3 N
> 55 N
output
17
input
2
> 100 Y
< -100 Y
output
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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值