【codejam2019 Round1A】Golf Gophers 题解

题目大意

  这是一道交互题。
  现在有若干只地鼠,你只知道地鼠数量 ≤ M \leq M M,你要把这个数量猜出来。
  你有 18 个风扇。每天初始,你给每个风扇设定它的叶片数 b i b_i bi(2 到 18 之间,从 0 开始标号),然后都让 0 号叶片指向正下。接着,每只地鼠独立地、等概率地选择一个风扇,把它的叶片往前拨一位(即原来是 j j j 号叶片向下的现在变成 ( j + 1 )   m o d   b i (j+1)~mod~b_i (j+1) mod bi 号叶片向下)。
  你告诉电脑 b b b 序列,它告诉你这天结束时各风扇指向正下的叶片编号。
  你要在至多 N N N 天之内猜出来。

   T a s k 1 : N = 365 ,   M = 100 Task1: N=365,~M=100 Task1:N=365, M=100
   T a s k 2 : N = 7 ,   M = 1 0 6 Task2: N=7,~M=10^6 Task2:N=7, M=106

题解

  Task1:
  没想出来。。。

  Task2:

看到 N = 7 N=7 N=7,马上想到 18 18 18 以内恰好只有 7 7 7 个质数,用这 7 7 7 个质数做模数,然后解中国剩余定理!!
——Zayin

  他从看完题到想出这一串东西总共用了 10s

  对于每一天,所有的风扇叶片数都取同一个模数 p p p,那么这一天你把最终状态加起来,就知道了地鼠数量 m o d    p \mod p modp 的值。
  7 天就把 2 、 3 、 5 、 7 、 11 、 13 、 17 2、3、5、7、11、13、17 2357111317 全部试一遍,这就有了 7 个同余方程。然后跑 CRT 就行了。
  根据 CRT,这个方程组在 2 ∗ 3 ∗ 5 ∗ . . . ∗ 17 = 510510 2*3*5*...*17=510510 235...17=510510 内有唯一解。

  好像不够大?那把 2 2 2 换成 16 16 16 3 3 3 换成 9 9 9 就可以啦!

代码

#include<bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

typedef long long LL;

const int maxs=50005, maxlen=55;

int n,m,p[7]={5,7,11,13,17,16,9};

LL ny(LL x,int pi)
{
	fo(i,1,p[pi]-1) if (x*i%p[pi]==1) return i;
}

int T;
int main()
{
	LL P=1;
	fo(i,0,6) P*=p[i];
	
	scanf("%d%d%d",&T,&n,&m);
	fo(ti,1,T)
	{
		LL ans=0;
		
		fo(i,0,6)
		{
			LL a=0;
			
			fo(j,1,18) printf("%d ",p[i]);
			puts("");
			fflush(stdout);
			
			fo(j,1,18)
			{
				int x;
				scanf("%d",&x);
				(a+=x)%=p[i];
			}
			
			(ans+=a*(P/p[i])%P*ny(P/p[i],i))%=P;
		}
		
		printf("%lld\n",ans);
		fflush(stdout);
		int res;
		scanf("%d",&res);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值