[USACO 2017 Open Gold] Tutorial
2024-10-21 06:25:25
Link:
A:
由于每个颜色只染色一次就确定了所有要染色的区间
要求染色的次数其实就是求区间最多嵌套多少层,如果有区间相交则无解
以上操作明显可以将左端点排序后用栈来维护
#include <bits/stdc++.h> using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=2e5+;
struct node{int x,d,col;};
node dat[MAXN];int st[MAXN],top;
int n,x,l[MAXN],r[MAXN],cur,res,tot;
bool cmp(node a,node b){return a.x==b.x?a.d<b.d:a.x<b.x;} int main()
{
scanf("%d",&n);
memset(l,0x3f,sizeof(l));
for(int i=;i<=n;i++)
{
scanf("%d",&x);
l[x]=min(l[x],i),r[x]=max(r[x],i);
if(!x) dat[++tot]=node{i,,};
}
for(int i=;i<=n;i++)
if(r[i]) dat[++tot]=node{l[i],,i},dat[++tot]=node{r[i],,i};
sort(dat+,dat+tot+,cmp); for(int i=;i<=tot;i++)
{//注意0代表没有颜色要特殊处理
if(!dat[i].col)
{
if(top) return puts("-1"),;
else continue;
}
if(!dat[i].d)
st[++top]=dat[i].col,cur++;
else
{
if(dat[i].col!=st[top])
return puts("-1"),;
top--;cur--;
}
res=max(res,cur);
}
printf("%d",res);
return ;
}
Problem A
注意零代表没有颜色要特殊处理……
B:
涉及字符串匹配想到哈希,结果一开始写成了$O(n^3*log(n))$
由于最外层的字符串长度的可行性是单调的,二分后可优化为$O(n^2*log(n)^2)$
但上述的复杂度是可以继续优化的
使用$two pointers$来利用单调性,每次可行就移动左端点,否则移动右端点
这样可以只检验$2*n$个字符串,复杂度降到了$O(2*n^2*log(n))$
同时该题也可以每次暴力构造$Trie$树来进行匹配,复杂度为$O(n^3)$
#include <bits/stdc++.h> using namespace std;
#define X first
#define RG register
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
typedef unsigned long long ull;
const int MAXN=1e3+,base=;
ull hs[MAXN][MAXN],pre[MAXN];
int n,m,f;char s[MAXN];
map<ull,int> mp; bool check(int x)
{
for(int i=x;i<=m;i++)
{
mp.clear();f=;
for(RG int k=;k<=n;k++)
mp[hs[k][i]-hs[k][i-x]*pre[x]]=;
for(RG int k=n+;k<=*n;k++)
if(mp[hs[k][i]-hs[k][i-x]*pre[x]]){f=;break;}
if(f) return true;
}
return false;
} int main()
{
scanf("%d%d",&n,&m);
pre[]=;
for(RG int i=;i<=m;i++) pre[i]=pre[i-]*base;
for(RG int i=;i<=*n;i++)
{
scanf("%s",s+);
for(RG int j=;j<=m;j++)
hs[i][j]=hs[i][j-]*base+(s[j]-'A');
} int l=,r=m;
while(l<=r)
{
int mid=(l+r)>>;
if(check(mid)) r=mid-;
else l=mid+;
}
printf("%d",l);
return ;
}
Problem B
$two pointers$对比二分的优越之处就在于其能更及时的纠错
如果当前长度不行就直接加长,而二分则要将该长度的所有字符串都检验过再进行调整
最新文章
- UIAutomator 编译
- 构建基于WinRT的WP8.1 App 02:数据绑定新特性
- iOS之隐藏状态栏
- 주기적으로 php파일 실행시키기 (PHP 파일 cron 으로 돌리기)
- IDE开发<;LER-Studio>;(2)::登录模块
- 网页上facebook分享功能的具体实现
- HTML基础总结<;文本格式>;
- nyoj三个水杯(bfs)
- 将一个int转成二进制c
- java多线程基本概述(七)——join()方法
- 本地和svn都删除文件导致版本不同的问题
- Appium+Python3+iOS真机环境搭建
- Redis常用命令【字符串】
- 搭建Hexo博客(四)-设置
- shell脚本总结
- mysqli_query数据库有数据,查不出来
- HTML5读取本地文件
- Swift - 构造函数
- OpenCV入门指南----人脸检测
- Python3 写Windows Service服务程序
热门文章
- TOYS(计算几何基础+点与直线的位置关系)
- lnmp、lamp、lnmpa一键安装包(Updated: 2016-4-12)
- AndroidStudio创建jinLibs文件夹
- Kaggle 数据挖掘比赛经验分享(转)
- sublime3插件安装及报错处理
- Linux 入门记录:三、Linux 文件基本操作管理
- 简单的自动化运维工具(shell+except+whiptail+功能模块化函数+循环)
- 安装:python+webdriver环境
- HIbernate学习笔记3 之 缓存和 对象的三种状态
- Django Ajax学习一