AtCoder Petrozavodsk Contest 001 C - Vacant Seat 交互题、带分类讨论的二分

C - Vacant Seat


Time limit : 2sec / Memory limit : 256MB

Score : 500 points

Problem Statement

This is an interactive task.

Let N be an odd number at least 3.

There are N seats arranged in a circle. The seats are numbered 0 through N1. For each i (0iN2), Seat i and Seat i+1 are adjacent. Also, Seat N1and Seat 0 are adjacent.

Each seat is either vacant, or oppupied by a man or a woman. However, no two adjacent seats are occupied by two people of the same sex. It can be shown that there is at least one empty seat where N is an odd number at least 3.

You are given N, but the states of the seats are not given. Your objective is to correctly guess the ID number of any one of the empty seats. To do so, you can repeatedly send the following query:

  • Choose an integer i (0iN1). If Seat i is empty, the problem is solved. Otherwise, you are notified of the sex of the person in Seat i.

Guess the ID number of an empty seat by sending at most 20 queries.

Constraints

  • N is an odd number.
  • 3N99 999

Input and Output

First, N is given from Standard Input in the following format:

N

Then, you should send queries. A query should be printed to Standart Output in the following format. Print a newline at the end.

i

The response to the query is given from Standard Input in the following format:

s

Here, s is VacantMale or Female. Each of these means that Seat i is empty, occupied by a man and occupied by a woman, respectively.

Notice

  • Flush Standard Output each time you print something. Failure to do so may result in TLE.
  • Immediately terminate the program when s is Vacant. Otherwise, the verdict is indeterminate.
  • The verdict is indeterminate if more than 20 queries or ill-formatted queries are sent.

Sample Input / Output 1

In this sample, N=3, and Seat 012 are occupied by a man, occupied by a woman and vacant, respectively.

InputOutput
3 
 0
Male 
 1
Female 
 2
Vacant

Source

AtCoder Petrozavodsk Contest 001

My Solution

题意:交互题,有一个周长为n的环形(3<=n<=99999),每一格是一个座位,每个位置要么坐着一个男人M要么女人F要么空的V,但安排座位M和M不能并列且F和F不能并列,所以n个座位中至少一个座位是空着的,通过交换的方式在20步之内找出一个空着的座位的坐标。

交互题、带分类讨论的二分

先输出l = 0 和 r = n-1,分别记录 a[l] 和 a[r]的是M或者F或者V。

然后二分mid,

然后r和mid之间有(r - mid - 1)个位置,

如果有奇数个位置,则当a[r] == a[mid]时,则在(l,mid)中必定有V 故r = mid,否则(mid, r)中必定有V故 l = mid。

如果有偶数个位置,则当a[r] != a[mid]时,则在(l,mid)中必定有V 故r = mid,否则(mid, r)中必定有V故 l = mid。

时间复杂度 O(logn)

空间复杂度 O(n)

#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 8;
 
string s;
int a[MAXN];
int main()
{
    #ifdef LOCAL
    //freopen("c.txt", "r", stdin);
    //freopen("c.out", "w", stdout);
    int T = 1;
    while(T--){
    #endif // LOCAL
    //ios::sync_with_stdio(false); cin.tie(0);
 
    LL n, i, l, r, mid;
    bool f;
    cin >> n;
    l = 0, r = n - 1;
 
    cout << l << "\n"; fflush(stdout);
    cin >> s;
    if(s[0] == 'M'){
        a[l] = 1;
    }
    else if(s[0] == 'F'){
        a[l] = 2;
    }
    else{
        a[l] = -1;
        return 0;
    }
 
    cout << r << "\n"; fflush(stdout);
    cin >> s;
    if(s[0] == 'M'){
        a[r] = 1;
    }
    else if(s[0] == 'F'){
        a[r] = 2;
    }
    else{
        a[r] = -1;
        return 0;
    }
 
    while(l + 1 < r){
        mid = (l+r)>>1;
        cout << mid << "\n"; fflush(stdout);
        cin >> s;
        if(s[0] == 'M'){
            a[mid] = 1;
        }
        else if(s[0] == 'F'){
            a[mid] = 2;
        }
        else{
            a[mid] = -1;
            return 0;
        }
 
        if((r - mid - 1)&1){
            if(a[mid] == a[r]){
                r = mid;
            }
            else{
                l = mid;
            }
        }
        else{
            if(a[r] != a[mid]){
                r = mid;
            }
            else{
                l = mid;
            }
        }
    }
 
 
    #ifdef LOCAL
    cout << endl;
    }
    #endif // LOCAL
    return 0;
}

  Thank you!

                                                                                                                                             ------from ProLights

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值