[BZOJ4207]Can
[BZOJ4207]Can
试题描述
输入
输出
对于每个case,输出一行,"Case #x: y z",x表示case标号(从1开始),y和z是答案区间的第一个和最后一个元素的下标。
输入示例
输出示例
Case #:
Case #:
Case #:
Case #:
数据规模及约定
题解
这是一道分治 + 暴搜的好题。
做法是这样的,我们在分治时考虑每次分治跨中点的部分,可以从中点开始向两边扩展,一旦遇到当前选的 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的更多相关文章
随机推荐
- python工具之exccel模板生成报表
from Db import Db from log import log import xlwt import xlrd from xlutils.copy import copy import s ...
- 你有学习者综合征吗?Web 开发是重灾区
[导读]:学习者综合征的主要表现:学而不用,不停学习,却没有真正实际应用知识来做东西.如果过去的一年里,学习的语言或框架超过三个,那可能已经感染学习者综合征了.Web 开发是重灾区咯. 你有学习者综合 ...
- Docker容器相关技术
docker需要依赖的Linux内核特性:(1)Namespaces 命名空间PID(Process ID) 用来隔离进程NET(Network) 管理网络接口IPC(InterProcess com ...
- ios 根据颜色生成图片,十六进制颜色。
//颜色生成图片方法 - (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size { CGRect rect = CGRectMake ...
- codevs 2905 足球晋级
时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description A市举行了一场足球比赛 一共有4n支队伍参加,分成n个小组(每小组4支队伍)进 ...
- asp.net mvc 5 微信接入VB版 - 获取AccessToken
获取AccessToken是微信接入的又一个基础操作.很多微信接口需要这个2小时一刷新的AccessToken作为参数. 转载请说明作者Nukepayload2 首先根据开发文档把获取AccessTo ...
- bitcoin 源码解析 - 交易 Transaction
bitcoin 源码解析 - 交易 Transaction(三) - Script 之前的章节已经比较粗略的解释了在Transaction体系当中的整体运作原理.接下来的章节会对这个体系进行分解,比较 ...
- xcode uml 工具
https://github.com/PaulTaykalo/objc-dependency-visualizer ./generate-objc-dependencies-to-json.rb -d ...
- Java之流水号生成器实现
参考:https://www.jianshu.com/p/331b872e9c8f 1.建立一张存放的表 CREATE TABLE `sys_serial_number` ( `id` bigint( ...
- dialog - 从 shell 显示对话框
总览 (SYNOPSIS) dialog --clear dialog --create-rc file dialog --print-maxsize dialog common-options bo ...