喵哈哈村的魔法考试 Round #15 (Div.2) 题解
哗啦啦村的奇迹果实(一)
题解:显然答案就是最大值减去最小值。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n,a[maxn];
int main(){
while(cin>>n){
int x;scanf("%d",&x);
int Mx = x;
int Mi = x;
for(int i=1;i<n;i++){
scanf("%d",&x);
Mx = max(Mx,x);
Mi = min(Mi,x);
}
cout<<Mx-Mi<<endl;
}
}
哗啦啦村的奇迹果实(二)
题解:虽然0可以与其他位置交换,但是0不改变其他数字的相对位置,所以只要找到相对位置,然后进行匹配即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int a[maxn],b[maxn],tot1,tot2,n;
int solve(){
tot1=0;
tot2=0;
for(int i=0;i<n;i++)
{
int x;scanf("%d",&x);
if(x==0)continue;
a[tot1++]=x;
}
for(int i=0;i<n;i++)
{
int x;scanf("%d",&x);
if(x==0)continue;
b[tot2++]=x;
}
int s=0;
for(int i=0;i<tot2;i++)
{
if(b[i]==a[0])
{
s=i;
break;
}
}
if(tot1!=tot2){
return puts("NO");
}
for(int i=0;i<tot1;i++)
if(a[i]!=b[(i+s)%(tot2)])
return puts("NO");
return puts("YES");
}
int main()
{
while(cin>>n)solve();
}
哗啦啦村的奇迹果实(三)
题解:动态规划。
f[i][j][0]表示当前小象位于格子(i,j)且上一个位置是(i-1,j)所看见的老鼠的最少数量。
f[i][j][1]表示当前小象位于格子(i,j)且上一个位置是(i,j-1)所看见的老鼠的最少数量。
f[i][j][0]=min(f[i-1][j][0]+a[i][j-1],f[i-1][j][1])+a[i+1][j]+a[i][j+1]
f[i][j][1]=min(f[i][j-1][0],f[i][j-1][1]+a[i-1][j])+a[i+1][j]+a[i][j+1]
answer=min(f[n][m][0],f[n][m][1])。
复杂度为 O(NM)。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1100
using namespace std;
int n,m;
int f[N][N];
int g[N][N];
int a[N][N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
memset(f,0x3f,sizeof(f));
memset(g,0x3f,sizeof(g));
f[1][1]=g[1][1]=a[1][1]+a[1][2]+a[2][1];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j-1>0)
f[i][j]=min(f[i][j],min(f[i][j-1]+a[i-1][j]+a[i][j+1]+a[i+1][j],g[i][j-1]+a[i][j+1]+a[i+1][j]));
if(i-1>0)
g[i][j]=min(g[i][j],min(f[i-1][j]+a[i][j+1]+a[i+1][j],g[i-1][j]+a[i][j-1]+a[i][j+1]+a[i+1][j]));
}
}
printf("%d\n",min(f[n][m],g[n][m]));
}
哗啦啦村的奇迹果实(四)
算法:最短路。
将“如果城市 B 愿意与城市 A 建立合作关系,当且仅当对于所有满足 d(A,C)<=d(A,B)的城市
C,都有 R(C)<=R(B)。”这一条件转化为“如果城市 B 愿意与城市 A 建立合作关系,当且仅当
对于所有满足 R(C)>R(B)的城市 C,都有 d(A,C)>d(A,B)。”
我们倒序枚举 R 的值 r,然后枚举 R(X)=r 的点 X,以每个点为起点对原图做最短路。设 lim[i]
表示所有点 K(R(K)>R(X))中到点 i 的最小距离,设 dist[i]表示 X 到 i 的最短路。对于点 i,在最
短路过程中,如果 dist[i]>=lim[i],那么表示比 X 的 R 值大的某个点到点 i 的最短距离要比 X
到 i 的距离短,所以 i 不会与 X 建立合作关系,而且不会用 dist[i]去更新其它点的最短路了。
因此,一个点用来更新其它点的条件是 dist[i]<lim[i],此时答案+1,因为答案<=30N,所以总
的更新次数不会超过 30N 次。所以最后复杂度为 O(kNlogN),k 为常数。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=30010,M=300100;
int n,m,nowRank;
int head[N],key[M],Next[M],len[M],cnt;
int Rank[N],dis[N],lim[N],minr[N];
int stack[N],tp;
int top,ans;
struct Heap
{
int x,w;
Heap(void){}
Heap(int _x,int _w):x(_x),w(_w){}
}heap[10*M];
void add(int x,int y,int z)
{
Next[++cnt]=head[x];
key[cnt]=y;
len[cnt]=z;
head[x]=cnt;
}
inline bool cmp(const Heap &a,const Heap &b)
{
if(a.w!=b.w) return a.w>b.w;
else return Rank[a.x]<Rank[b.x];
}
void dijk()
{
while(top)
{
Heap sta=heap[1];
pop_heap(heap+1,heap+top+1,cmp);
top--;
if(sta.w!=dis[sta.x]) continue;
stack[++tp]=sta.x;
for(int i=head[sta.x];~i;i=Next[i])
{
if(Rank[key[i]]>nowRank) continue;
if(dis[key[i]]>sta.w+len[i]&&lim[key[i]]>sta.w+len[i])
{
dis[key[i]]=sta.w+len[i];
heap[++top]=Heap(key[i],dis[key[i]]);
push_heap(heap+1,heap+top+1,cmp);
}
}
}
}
int main()
{
memset(head,-1,sizeof head);
memset(dis,0x3f,sizeof dis);
memset(lim,0x3f,sizeof lim);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&Rank[i]);
for(int i=1,x,y,z;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
for(int i=10;i>=1;i--)
{
nowRank=i;
memset(minr,0x3f,sizeof minr);
for(int j=1;j<=n;j++)
if(Rank[j]==i)
{
heap[++top]=Heap(j,0);
dis[j]=0;
dijk();
for(;tp;tp--)
{
int k=stack[tp];
if(lim[k]>dis[k]) ans++;
minr[k]=min(minr[k],dis[k]);
dis[k]=INF;
}
}
for(int j=1;j<=n;j++)
lim[j]=min(minr[j],lim[j]);
}
cout<<ans<<endl;
return 0;
}
哗啦啦村的奇迹果实(五)
算法:字符串 hash
枚举两段的长度 len 和第一段的起点 i,我们定义 L 为第一段与第二段的最长公共后缀,当
L>=len 的时候答案+1,而起点为 i+1 时 L 的大小仅仅取决于起点为 i 时 L 大小和 a[i+len]与
a[i+2len+F]的相等关系:
L[i+1] = L[i] + 1 (a[i+len]=a[i+2len+F])
L[i+1] = 0 (a[i+len]!=a[i+2*len+F])
这样朴素的枚举 len 后扫描整个序列是 N^2 的,我们考虑优化这个算法。
首先枚举两段的长度 len,然后我们在递推的时候可以发现,在长度为 len 时,我们没有必
要一格一格的递推,而可以每次向右递推 len 格。我们不妨设第一段的末尾位置为 i,第二
段的末尾位置为 j,设 frontL 表示 a[i+1]„a[i+len]与 a[j+1]„a[j+len]的最长公共前缀,设 backL
表示 a[i+1]„a[i+len]与 a[j+1]„a[j+len]的最长公共后缀,令 L 表示当前的最长公共后缀。
下面分两种情况考虑对于答案的贡献:
情况一:如果 L>=len,ans+=frontL。
情况二:反之,ans+=max(0,L+frontl-i+1)。
下面分两种情况考虑递推后的最长公共后缀 nL:
情况一:如果 a[i+1]„a[i+len]与 a[j+1]„a[j+len]整段相同,nL=L+len。
情况二:反之,nL=backl。
这样对于每个长度 len,需要递推 N/len 次,每次采用 hash+二分的方法 O(logN)的计算最长
公共前/后缀,总的复杂度为 O(NlnNlogN)。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<ctime>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
const int N=1000010;
const ull mul=133331;
ll ans;
int n,m,k;
int b[N],a[N];
int X[N];
ull Hash[N];
ull f[N]={1};
inline int bin(int x)
{
int l=1,r=k;
while(l<=r)
{
int mid=l+r>>1;
if(b[mid]<=x) l=mid+1;
else r=mid-1;
}
return r;
}
inline ull getHash(const int &l,const int &r)
{
return Hash[r]-Hash[l-1]*f[r-l+1];
}
inline int lcp(int x,int y)
{
int l=0,r=min(n-x+1,n-y+1);
while(l<=r)
{
int mid=l+r>>1;
if(getHash(x,x+mid-1)==getHash(y,y+mid-1)) l=mid+1;
else r=mid-1;
}
return r;
}
inline int anti_lcp(int x,int y)
{
int l=0,r=min(x,y);
while(l<=r)
{
int mid=l+r>>1;
if(getHash(x-mid+1,x)==getHash(y-mid+1,y)) l=mid+1;
else r=mid-1;
}
return r;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
X[i]=a[i];
}
sort(X+1,X+n+1);
X[0]=~0U>>1;
for(int i=1;i<=n;i++)
if(X[i]!=X[i-1])
b[++k]=X[i];
for(int i=1;i<=n;i++)
a[i]=bin(a[i]);
for(int i=1;i<=n;i++) f[i]=f[i-1]*mul;
for(int i=1;i<=n;i++) Hash[i]=Hash[i-1]*mul+a[i];
for(int i=1;2*i+m<=n;i++)
{
int nowl=0;
for(int j=1;;)
{
int len=min(i,n-(j+i+m-1));
if(!len) break;
int frontl=lcp(j,j+i+m);
int backl=anti_lcp(j+len-1,j+m+i+len-1);
frontl=min(frontl,len);
backl=min(backl,len);
if(frontl==len)
{
if(nowl>=i) ans+=len;
else ans+=max(0,nowl+frontl-i+1);
nowl+=len;
}
else
{
if(nowl>=i) ans+=frontl;
else ans+=max(0,nowl+frontl-i+1);
nowl=backl;
}
j+=len;
}
}
cout<<ans<<endl;
return 0;
}
喵哈哈村的魔法考试 Round #15 (Div.2) 题解的更多相关文章
- 喵哈哈村的魔法考试 Round #2 (Div.2) 题解
喵哈哈村的魔法考试 Round #2 (Div.2) 题解 A.喵哈哈村的战争 题解: 这道题就是for一遍,统计每个村子的战斗力的和,然后统计哪个村子的战斗力和大一点就好了. 唯一的坑点,就是这道题 ...
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解
喵哈哈村的魔法考试 Round #1 (Div.2) 题解 特别感谢出题人,qscqesze. 也特别感谢测题人Xiper和CS_LYJ1997. 没有他们的付出,就不会有这场比赛. A 喵哈哈村的魔 ...
- 喵哈哈村的魔法考试 Round #7 (Div.2) 题解
喵哈哈村的魔法考试 Round #7 (Div.2) 注意!后四道题来自于周日的hihocoder offer收割赛第九场. 我建了个群:欢迎加入qscoj交流群,群号码:540667432 大概作为 ...
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&源码(A.水+暴力,B.dp+栈)
A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05 最后更新: 2017年2月21日 20:06 时间限制: 1000ms 内存限制: 128M 描述 传说喵哈哈村有三种神 ...
- 喵哈哈村的魔法考试 Round #19 (Div.2) 题解
题解: 喵哈哈村的魔力源泉(1) 题解:签到题. 代码: #include<bits/stdc++.h> using namespace std; int main(){ long lon ...
- 喵哈哈村的魔法考试 Round #14 (Div.2) 题解
喵哈哈村的四月半活动(一) 题解: 唯一的case,就是两边长度一样的时候,第三边只有一种情况. #include <iostream> #include <cstdio> # ...
- 喵哈哈村的魔法考试 Round #4 (Div.2) 题解
有任何疑问,可以加我QQ:475517977进行讨论. A 喵哈哈村的嘟嘟熊魔法(1) 题解 这道题我们只要倒着来做就可以了,因为交换杯子是可逆的,我们倒着去模拟一遍就好了. 有个函数叫做swap(a ...
- 喵哈哈村的魔法考试 Round #20 (Div.2) 题解
题解: A 喵哈哈村的跳棋比赛 题解:其实我们要理解题意就好了,画画图看看这个题意.x<y,那么就交换:x>y,那么x=x%y. 如果我们经过很多次,或者y<=0了,那么就会无限循环 ...
- 喵哈哈村的魔法考试 Round #18 (Div.2) 题解
喵哈哈村的古怪石碑(一) 题解:暴力check一下是等比数列还是等差数列,然后输出答案即可.注意如果数据范围是1e9的话,就要快速幂了. 代码: #include <cstdio> #in ...
随机推荐
- VC++文件拖放
属性Accept Files 设置True,消息WM_DROPFILES 设置事件OnDropFiles void CNWiReworkDlg::OnDropFiles(HDROP hDropInfo ...
- 单例模式(懒汉、饿汉、同步锁、static、枚举)实现
使用前提: 需要频繁的进行创建和销毁的对象,创建对象时耗时过多或耗费资源过多 三要素: 1.构造方法私有化: 2.实例化的变量引用私有化: 3.获取实例的方法共有. 1.饿汉式单例 弊端:在类装载的时 ...
- MySQL 数据类型(转)
MySQL 数据类型 在 MySQL 中,有三种主要的类型:文本.数字和日期/时间类型. Text 类型: 数据类型 描述 备注 CHAR(size) 保存固定长度的字符串(可包含字母.数字以及特殊字 ...
- 错误代码 1045 Access denied for user 'root'@'localhost' (using password:YES)
1 前言 现象是用MySQL 5.7 Command Line Client可以使用root账号进入,但是其它navicat,phpsqladmin,mysql workbench,heidisql用 ...
- 【转载】如何让图片按比例响应式缩放、并自动裁剪的css技巧
原文: http://blog.csdn.net/oulihong123/article/details/54601030 响应式网站.移动端页面在DIV CSS布局中对于图片列表或图片排版时, 如果 ...
- hdu3486 ST表区间最值+二分
还是挺简单的,但是区间处理的时候要注意一下 #include<iostream> #include<cstring> #include<cstdio> #inclu ...
- swich使用
package demo; import java.util.Scanner; /** * swich(变量){//byte\shore\char\int'枚举(jdk1.5)/String(1.7) ...
- 【C++ Primer 第10章】 10.4.2 插入迭代器
iostream迭代器 标准库为iostream定义了可用于这些IO类型对象的迭代器. istream_iterator读取输入流, ostream_iterator向一个输出流写数据. 1. i ...
- ORACLE分页查询SQL语法——高效的分页
--1:无ORDER BY排序的写法.(效率最高)--(经过测试,此方法成本最低,只嵌套一层,速度最快!即使查询的数据量再大,也几乎不受影响,速度依然!) SELECT * FROM (SELECT ...
- .NetCore下使用Prometheus实现系统监控和警报 (五)进阶自定义收集指标 之 Counter
Prometheus下面定了四种类型的收集方式,下面我们主要来来说下Counter的使用 Nuget导入Prometheus.AspNetCore包 下面先来看下我的Prometheus配置,这里我没 ...