P9311 [EGOI2021] Twin Cookies / 姐妹分饼干 题解

题目传送门/AC record

思路

考虑随机化,前 \(100\) 次订单的美味值随机生成,最后一次的 \(n\) 个美味值为前 \(100\) 次送到的饼干中的任意三个饼干的美味值之和,此时的组合方案数去重后也远大于 \(n\),故可以通过。

选取饼干和最后的分配直接暴力计算就行,判重可以用 map

代码

#include<bits/stdc++.h>
using namespace std;
const long long mod=1e16;
map<long long,bool>a;
int n;
long long f[114];
long long d[5145],l;
int main() {
	srand(time(0));
	cin>>n;
	for(int i=1;i<=100;i++) {
		for(int j=1;j<=n;j++) {
			long long k=rand()*rand()*rand();//生成随机美味值
			k=abs(k)%mod+1;
			while(a[k]) {
				k=rand()*rand()*rand();
				k=abs(k)%mod+1;
			}
			a[k]=true;
			d[j]=k;
		}
		cout<<"? ";
		for(int j=1;j<=n;j++)cout<<d[j]<<" ";
		cout<<endl;
		cin>>f[i];
	}
	for(int i=1;i<=100;i++) {
		for(int j=i+1;j<=100;j++) {
			for(int x=j+1;x<=100;x++) {
				long long k=f[i]+f[j]+f[x];
				if(k>mod||a[k])continue;//记得判断k>10^16的情况
				a[k]=true;
				d[++l]=k;
				if(l==n)break;
			}
			if(l==n)break;
		}
		if(l==n)break;
	}
	cout<<"? ";
	for(int i=1;i<=n;i++)cout<<d[i]<<" ";
	cout<<endl;
	cin>>l;
	for(int i=1;i<=100;i++) {
		for(int j=i+1;j<=100;j++) {
			for(int x=j+1;x<=100;x++) {
				long long k=f[i]+f[j]+f[x];
				if(k==l) {
					cout<<"! 1 3"<<endl;
					cout<<k<<endl;
					cout<<f[i]<<" "<<f[j]<<" "<<f[x]<<endl;
					return/*191981*/0;//华丽收尾 
				} 
			}
		}
	}
}
posted @ 2024-12-15 13:25  ni_ju_ge  阅读(47)  评论(0)    收藏  举报