1. 程式人生 > 實用技巧 >習題:Guess The Maximums(二分)

習題:Guess The Maximums(二分)

題目

傳送門

思路

如果一個集合不包含最大值,那麼他的答案一定是最大值

用二分找最小值就行了只需要

最後單獨詢問一下即可

程式碼

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
int t;
int n,k;
int ans[1005];
int bel[1005];
void c_in()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++)
        bel[i]=-1;
    for(int i=1;i<=k;i++)
    {
        int len;
        scanf("%d",&len);
        for(int j=1;j<=len;j++)
        {
            int u;
            scanf("%d",&u);
            bel[u]=i;
        }
    }
    int l=1,r=n,mid,la,now,maxx;
    printf("? %d",n);
    for(int i=1;i<=n;i++)
        printf(" %d",i);
    printf("\n");
    fflush(stdout);
    scanf("%d",&la);
    maxx=la;
    while(l!=r)
    {
        mid=(l+r)>>1;
        printf("? %d",mid-l+1);
        for(int i=l;i<=mid;i++)
            printf(" %d",i);
        printf("\n");
        fflush(stdout);
        scanf("%d",&now);
        if(la==now)
            r=mid;
        else
            l=mid+1;
    }
    int s=0;
    for(int i=1;i<=n;i++)
        if(bel[i]!=bel[l])
            s++;
    printf("? %d",s);
    for(int i=1;i<=n;i++)
        if(bel[i]!=bel[l])
            printf(" %d",i);
    printf("\n");
    fflush(stdout);
    scanf("%d",&now);
    printf("!");
    for(int i=1;i<=k;i++)
    {
        if(bel[l]==i)
            printf(" %d",now);
        else
            printf(" %d",maxx);
    }
    printf("\n");
    fflush(stdout);
}
int main()
{
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        c_in();
        scanf("%*s");
    }
    return 0;
}