CodeForces 1167 B Lost Numbers 交互题

TP

交互题: 每次输出后都要加

fflush(stdout);

 

题意: 给出一个集合: 44, 88, 1515, 1616, 2323, 4242. 现在有一个数组, 他是集合的一种排列, 现在你可以向评测姬询问最多4个问题, "a[i]*a[j]是多少吖?" 然后评测姬就会告诉你这个数. 之后, 你就要输出这个数组了.

思路: 因为只有4个数, 两两乘积是唯一的, 那么可以问一下a[1]*a[2], a[1]*a[3], a[4]*a[5], a[4]*a[6]. 其中, a[1]*a[2]和a[1]*a[3]就能确定a[1], a[2]和a[3]. a[4]*a[5]和a[4]*a[6]就能确定a[4], a[5]和a[6]. 实际操作的话, 要写一堆if...

实际上, 只要我知道询问了"a[1]*a[2], a[1]*a[3], a[4]*a[5], a[4]*a[6]."就能唯一确定一种排列, 那么我们就可以枚举所有的排列, 合适的那个就是答案了...(next_permutation)

一堆if的写法:

#include<bits/stdc++.h>
#define fuck(x) std::cout<<"["<<#x<<"->"<<x<<"]"<<endl;
using namespace std;
typedef long long ll;

const int M=2e5+5;
const int inf=1e9+5;
const int mod=1e9+7;
map<int,pair<int,int> >mp;

int x[]={4 , 8, 15, 16, 23, 42};
int main() {
    for(int i=0;i<6;i++){
        for(int j=i+1;j<6;j++){
                mp[x[i]*x[j]]=make_pair(i,j);
        }
    }
    int a,b,c,d,e,f;
    int ab;
    printf("? 1 2\n");
    fflush(stdout);
    scanf("%d",&ab);
    int _a,_b;
    _a=mp[ab].first,_b=mp[ab].second;
    int ac;
    printf("? 1 3\n");
    fflush(stdout);
    scanf("%d",&ac);
    int __a,_c;
    __a=mp[ac].first,_c=mp[ac].second;
    if(_a==__a){
        a=_a;
        b=_b;
        c=_c;
    }else if(_a==_c){
        a=_a;
        b=_b;
        c=__a;
    }else if(_b==__a){
        a=_b;
        b=_a;
        c=_c;
    }else{
        a=_b;
        b=_a;
        c=__a;
    }

    int de;
    printf("? 4 5\n");
    fflush(stdout);
    scanf("%d",&de);
    int _d,_e;
    _d=mp[de].first,_e=mp[de].second;
    int df;
    printf("? 4 6\n");
    fflush(stdout);
    scanf("%d",&df);
    int __d,_f;
    __d=mp[df].first,_f=mp[df].second;
    if(_d==__d){
        d=_d;
        e=_e;
        f=_f;
    }else if(_d==_f){
        d=_d;
        e=_e;
        f=__d;
    }else if(_e==__d){
        d=_e;
        e=_d;
        f=_f;
    }else{
        d=_e;
        e=_d;
        f=__d;
    }

    printf("! %d %d %d %d %d %d\n",x[a],x[b],x[c],x[d],x[e],x[f]);
    return 0;
}

枚举排列的写法:

#include<bits/stdc++.h>
#define fuck(x) std::cout<<"["<<#x<<"->"<<x<<"]"<<endl;
using namespace std;
typedef long long ll;

int x[]= {4, 8, 15, 16, 23, 42};
int main() {
    int ab;
    printf("? 1 2\n");
    fflush(stdout);
    scanf("%d",&ab);
    int ac;
    printf("? 1 3\n");
    fflush(stdout);
    scanf("%d",&ac);
    int de;
    printf("? 4 5\n");
    fflush(stdout);
    scanf("%d",&de);
    int df;
    printf("? 4 6\n");
    fflush(stdout);
    scanf("%d",&df);
    do {
        if(x[0]*x[1]==ab&&x[0]*x[2]==ac&&x[3]*x[4]==de&&x[3]*x[5]==df) {
            printf("! %d %d %d %d %d %d\n",x[0],x[1],x[2],x[3],x[4],x[5]);
            break;
        }
    } while(next_permutation(x,x+6));
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值