[BZOJ4207]Can

试题描述

这个问题是源于一个在棋盘上玩的,由Sid Sackson设计的名叫Can't stop的游戏的。这个问题与Can't stop有一定的相似之处,但是不需要玩过Can't stop。
你在玩一个(非常大型的)棋盘游戏。在这个游戏里面,给出了一个长度为N的roll set的序列。每个roll set包括D个die roll,每个die roll是一个正整数。
你需要找到序列中总长度最大的极好的区间。区间即为连续的一段roll set。如果存在k个数使某个区间内的所有roll set都至少包含其中一个,那么,这个区间就被认为是极好的。
例如:d=2,k=3时,roll set如下:
 
Set 0: 10 20
Set 1: 50 60
Set 2: 70 30
Set 3: 40 40
Set 4: 30 30
Set 5: 20 40
从0到2的区间是极好的,因为从0到2中的每个roll set都包含了10,50或70 。从1到5的区间也是极好的,因为1到5的所有roll set都包含50,30或40。它包含了5个roll set,是总长度最大的极好的区间。
你的任务是输出总长度最大的极好的区间的第一个元素的下标和最后一个元素的下标。如果有多个长度一样的,输出第一个元素下标最小的。请注意下标从0开始。

输入

第一行包含一个整数T,表示数据组数。接下来T组数据。
每组数据的第一行是三个正整数N,D,k,描述如上。接下来一行,包含N*D个整数,前D个整数表示第一个roll set ,接下来D个表示第二个roll set,以此类推。

输出

对于每个case,输出一行,"Case #x: y z",x表示case标号(从1开始),y和z是答案区间的第一个和最后一个元素的下标。

输入示例


输出示例

Case #:
Case #:
Case #:
Case #:

数据规模及约定

对于45%的数据,N<=1000
对于50%的数据,k=2
前两部分数据共计70%
对于100%的数据,2<=k<=3
输入文件在4.8M以内
T=10.
1 ≤ D ≤ 4.
1 ≤ 每个die roll ≤ 10^5.
对于最多6个case, 1 ≤ N ≤ 10^5.
对于其他所有的case, 1 ≤ N ≤ 10^3.

题解

这是一道分治 + 暴搜的好题。

做法是这样的,我们在分治时考虑每次分治跨中点的部分,可以从中点开始向两边扩展,一旦遇到当前选的 k’ 个数不能搞掉的 roll set,就枚举一下选择这个 roll set 中的哪一个 die roll,然后接着向左右扩展。

最优性剪枝能剪掉不少情况。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 100010
int n, D, K, A[maxn][4], num[maxn<<2]; bool has[maxn<<2];
int al, ar;
bool can(int p) {
for(int i = 0; i < D; i++) if(has[A[p][i]]) return 1;
return 0;
}
void dfs(int l, int r, int ql, int qr, int k) {
while(l >= ql && can(l)) l--;
while(r <= qr && can(r)) r++;
// printf("dfs: %d %d\n", l, r);
int len = r - l - 1;
if(len > ar - al + 1) al = l + 1, ar = r - 1;
if(len == ar - al + 1 && l + 1 < al) al = l + 1, ar = r - 1;
if(k == K) return ;
if(l < ql && r > qr) return ;
for(int i = 0; i < D; i++) {
if(l >= ql) has[A[l][i]] = 1, dfs(l - 1, r, ql, qr, k + 1), has[A[l][i]] = 0;
if(r <= qr) has[A[r][i]] = 1, dfs(l, r + 1, ql, qr, k + 1), has[A[r][i]] = 0;
}
return ;
}
void solve(int l, int r) {
if(ar - al + 1 > r - l + 1 || l > r) return ;
int mid = l + r >> 1;
// printf("[%d, %d] %d\n", l, r, mid);
dfs(mid, mid, l, r, 0);
solve(l, mid - 1); solve(mid + 1, r);
return ;
} int main() {
int T = read();
for(int kase = 1; kase <= T; kase++) {
n = read(); D = read(); K = read();
int cnt = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < D; j++) num[++cnt] = A[i][j] = read();
sort(num + 1, num + cnt + 1);
for(int i = 0; i < n; i++)
for(int j = 0; j < D; j++) A[i][j] = lower_bound(num + 1, num + cnt + 1, A[i][j]) - num;
al = ar = 0;
solve(0, n - 1);
printf("Case #%d: %d %d\n", kase, al, ar);
} return 0;
}

[BZOJ4207]Can的更多相关文章

随机推荐

  1. 用IARIdePm新建STM8工程步骤

    IARdePm 如何新建工程及其调用库函数1.新建文件夹,例如,新建文件夹名字(不能为中文)为:Lib_test_GPIO_OUT2.新建工程,Create New Project...,选择Empt ...

  2. js删除最后一个字符

    在最近做一个系统,使用socket来完成后台操作,C#来完成前端操作.但是在定的协议里面,一定要用某个符号来表示传的数据结束.后台进行交互时,获取到的数据必须进行删除最后一个字符的操作. 比如我们协议 ...

  3. 【前端】jQurey Plugin

    ; (function ($, window, document, undefined) { "use strict"; var defaults = { name: " ...

  4. 如何从GAC中拷贝文件出来 C:\Windows\assembly

    方法一:命令行拷贝. 开始--运行--cmd--"cd C:\WINDOWS\assembly".一般自己开发的dll都在GAC_MSIL这个文件夹下面,按照我如下的截图就可以拷贝 ...

  5. AJPFX浅谈Java新手问题之缺少良好的编程习惯

    ★随意地命名 有些新手写程序,当需要定义某个变量名(也可能是函数名.类名.包名等)时,随意地一敲键盘,名字就起好了......若干星期后,碰到某 bug,再来看自己写的代码时,心中暗自嘀咕:“这代码是 ...

  6. [BZOJ1045][HAOI2008]糖果传递 数学

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1045 我们假设每一个小朋友的代价为$x[i]$,每一次都从前面一个小朋友那里拿,这种贪心跟 ...

  7. 找不到draw9patch.bat?已经不用找了

    Google 已经因为 draw9patch 热门的原因,把它集成在 Android Studio 里面了, 你现在可以直接在 Android Studio 里直接打开编辑了.

  8. Microsoft Windows Server 系统基本配置

    Microsoft Windows Server 系统基本配置 环境基本配置 桌面和显示属性 更新服务器名称 更新用户密码 创建密码重置盘 设置网络类型 TCP/IP设置 ping和ipconfig命 ...

  9. python爬虫---实现项目(二) 分析Ajax请求抓取数据

    这次我们来继续深入爬虫数据,有些网页通过请求的html代码不能直接拿到数据,我们所需的数据是通过ajax渲染到页面上去的,这次我们来看看如何分析ajax 我们这次所使用的网络库还是上一节的Reques ...

  10. ES6 第三章 变量的解构赋值 具体参照http://es6.ruanyifeng.com

    1.基本用法 let [a, b, c] = [1, 2, 3];左右两边解构格式要保持一致. 2.默认值 let [x, y = 'b'] = ['a']; // x='a', y='b' let ...