首页 > 其他分享 >【题解】[FARIO2013]Torusia

【题解】[FARIO2013]Torusia

时间:2022-08-19 15:23:30浏览次数:48  
标签:rd 标记 int 题解 Torusia FARIO2013 while 63 64

通信题,小 A 和小 B 迷失在 \(4096\times 4096\) 的方阵中。
方阵是循环的,比如 \((0,4095)\) 的右边是 \((0,0)\),上面是 \((4095,4095)\)。两人都不知道自己的绝对位置。每一秒钟小 A 可以在他坐标系下的某个点打上标记,然后小 B 询问在他坐标系下 一行一列 中标记个数。你需要尽快让小 B 知道在他坐标系下小 A 的坐标,所花时间为 \(x\),得分为 \(\min\{100,10 + \dfrac{13000}{x}\}\)。

\(x = 144\) 即可满分。

我们先考虑怎么求行,\(4096 = 64^2\),小 A 先将所有 \((64p, 64q)\) 的点打上标记。小 B 询问 \(0\sim 63\) 行/列即可知道最终坐标为 \((64p + a, 64q + b)\) 中的 \(a,b\)。相当于转化为 \(64 \times 64\) 的子问题。这个方法大概需要 \(256\) 秒。

开始填充标记需要 \(64\) 次,找到 \(a,b\) 各需要 \(64\) 次,我们可以将 填充和寻找放到一起,记得将询问和标记随机,这样期望在 \(128\) 次之内就找到。

但是对于 \(64\times 64\) 的子问题不可能用相同的方法。因为我们只剩最后 \(16\) 次操作可以进行。这恰好是一个倍增的复杂度。我们构造标记,使得 \(p,q\ge 32\) 的行/列,恰好每行/列 \(1\) 个标记,\(\ge16\) 的恰好 \(2\) 个标记,依此类推。我们要求的是第 \(0\) 行的坐标,这样每次询问当前行的标记数量,可以将规模减半,比如标记数量为 \(2\),说明 \(16\le x<32\),我们直接将 \(x - 16\)。

因为这个网站没有配置好通信题,所以下面代码的通信方式有点大病(

应该还有优化 / 更好的实现方法。下面这份代码代码分数在 \(99\) 附近波动。

下面是小 A 的代码

void alison(){
	for(int i = 0; i < 4096; i += 64)mark(i, i);
	int s = 32;
	while(s > 1){
		int p = s / 2;
		rep(i, 0, s - 1)mark(p * 64, i * 64), p = (p + 1) % s;
		s = p;
	}
}

下面是小 B 的代码

int p[100], q[100];
std::mt19937 rd(7274482);
inline void su(int &x,int y){
	x -= y; if(x < 0)x += 4096;
}
void bill(){
	rep(i, 0, 63)p[i] = i + (rd() & 63) * 64, q[i] = i + (rd() & 63) * 64;
	shuffle(p, p + 64, rd), shuffle(q, q + 64, rd);
	int x = 0, y = 0, t = 0;
	while(true){
		++t; 
		if(numRow(p[t & 63])){x = p[t & 63]; break;}
	}
	while(true){
		++t;
		if(numColumn(q[t & 63])){y = q[t & 63]; break;}
	}
	while(t < 127)numRow(0), t++;
	while(true){
		int w = numRow(x);
		if(w == 6)break;
		su(x, (1 << (5 - w)) * 64); 
	}
	if(numRow((x + 64) & 4095) != 6)su(x, 64);
	while(true){
		int w = numColumn(y);
		if(w == 6)break;
		su(y, (1 << (5 - w)) * 64);
	}
	if(numColumn((y + 64) & 4095) != 6)su(y, 64);
	found(y, x);
}

标签:rd,标记,int,题解,Torusia,FARIO2013,while,63,64
From: https://www.cnblogs.com/7KByte/p/16602081.html

相关文章

  • 桐柏邀请赛 S10 题解
    EnchantedLove记\(S=a_1+a_2+\cdots+a_n\),那么:若\(S\)为偶数,则答案为\(\frac{S}{2}\)。否则,我们找到\(a\)中最小的奇数(显然此时\(a\)中必然有至少一个奇数),设......
  • 【题解】CF1720C
    题意简述给你一个01矩阵,每一次你可以在这个矩阵中找到一个\(L\)型,将它全部变成0。\(L\)型的定义是在一个\(2*2\)矩阵中,除开一个角之外的图形,其中必须包含至少一个......
  • QT“程序异常结束”问题解决
    今天用QT写个小程序,出现了一个小问题,就是程序编译通过了,也能运行,但是有一个按键按下后程序就会异常结束。解决办法:由于文件中有多个类,而使用某个类的函数时,存在对象只声......
  • P1967 [NOIP2013 提高组] 货车运输 题解
    题目描述A国有\(n\)座城市,编号从\(1\)到\(n\),城市之间有\(m\)条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有\(q\)辆货车在运输货物,司机们想知道......
  • 题解P2143 [JSOI2010] 巨额奖金
    题意就是让你求有多少种最小生成树生成树用kruskal求就好了我们考虑用dfs中用乘法原理去计数#include<bits/stdc++.h>#defineN1000100usingnamespacestd;ty......
  • ARC097E题解
    感觉挺一眼的啊?众所周知如果序列\(i\)要通过相邻两项交换变成\(p_i\),那么交换次数就是\(\sum_{i<j}[p_i>p_j]\),或者说线段\((i,p_i)\)相交的对数。于是一个很naiv......
  • 【题解】 洛谷P3694 邦邦的大合唱站队
    发现尽管\(n\)比较大,但\(m\)非常小,于是考虑状压。记\(dp_{i}\)表示满足条件的乐队集合为\(i\)时的最小出队人数,\(dp_i=\min\{dp_{i\\xor\\1<<k}\}+w_{i\\xo......
  • [CF1450F] The Struggling Contestant 题解
    \(\mathtt{Link}\)CF1450FTheStrugglingContestant-洛谷|计算机科学教育新生态(luogu.com.cn)\(\mathtt{Description}\)\(T\)组数据。一共有\(n\)道题,题号......
  • P5080 Tweetuzki 爱序列 题解
    题目传送门更好地阅读体验题目大意Tweetuzki有一个长度为\(n\)的序列\(a_1,a_2,\cdots,a_n\)。他希望找出一个最大的\(k\),满足在原序列中存在一些数\(b_1,b......
  • IOI 2022 简要题解
    考前写题解增加RP。D1T1:考虑按照列DP。对于每一列选择的鱼的区间进行决策。每列中被选择的y坐标最大的鱼,需要被左面或右面覆盖。假设我们决策好了前i列的方案,考虑第i列......