1 条题解

  • 0
    @ 2026-5-6 10:25:10

    注意到本题饼干美味度的值域很大,为 [1,1016][1,10^{16}],考虑使用随机化算法。

    注意到前面的 100100 次我们可以订购 100100 块美味度随机的饼干,然后最后一次订购的每一块饼干的美味度都是从前面的 100100 块饼干中选出 33 块美味度之和,这样如果不考虑美味度的重复,一共会有 C1003=161700C^3_{100}=161700 种美味度,远大于一次需要订购的 n(nmax=5×103)n\left(n_{\max}=5\times 10^3\right),所以美味度重复的影响可以忽略不计。

    实现的时候每次订购的饼干的美味度可以用 std::map 判重。

    放代码:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    main(){
      ios::sync_with_stdio(false);
      int n; cin>>n;
      vector<int> a(100),s;
      mt19937 g(7202303); // 随机数生成器
      uniform_int_distribution<int> u(1,2e15);
      map<int,bool> m,m2;
      for(int i=0;i<100;i++){
        cout<<"? ";
        for(int j=1;j<=n;j++){
          int x=u(g);
          while(m[x])x=u(g); // 美味度重复了就一直生成
          cout<<x<<' '; m[x]=true;
        }
        cout<<endl; cin>>a[i];
      }
      for(int i=0;i<98;i++)
        for(int j=i+1;j<99;j++)
          for(int k=j+1;k<100&&s.size()<n;k++)
            if(!m2[a[i]+a[j]+a[k]])
              s.emplace_back(a[i]+a[j]+a[k]),m2[a[i]+a[j]+a[k]]=true;
      cout<<"? ";
      for(int i:s)cout<<i<<' '; // 最后一次订购
      cout<<endl; int r; cin>>r;
      cout<<"! 1 3"<<endl<<r<<endl;
      for(int i=0;i<98;i++)
        for(int j=0;j<99;j++)
          for(int k=0;k<100;k++)
            if(r==a[i]+a[j]+a[k]) // 找到求和的 3 块饼干
              cout<<a[i]<<' '<<a[j]<<' '<<a[k]<<endl,exit(0);
    }
    
    • 1

    信息

    ID
    10950
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者