哗啦啦村的奇迹果实(一)

题解:显然答案就是最大值减去最小值。

#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+2
len+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) 题解的更多相关文章

  1. 喵哈哈村的魔法考试 Round #2 (Div.2) 题解

    喵哈哈村的魔法考试 Round #2 (Div.2) 题解 A.喵哈哈村的战争 题解: 这道题就是for一遍,统计每个村子的战斗力的和,然后统计哪个村子的战斗力和大一点就好了. 唯一的坑点,就是这道题 ...

  2. 喵哈哈村的魔法考试 Round #1 (Div.2) 题解

    喵哈哈村的魔法考试 Round #1 (Div.2) 题解 特别感谢出题人,qscqesze. 也特别感谢测题人Xiper和CS_LYJ1997. 没有他们的付出,就不会有这场比赛. A 喵哈哈村的魔 ...

  3. 喵哈哈村的魔法考试 Round #7 (Div.2) 题解

    喵哈哈村的魔法考试 Round #7 (Div.2) 注意!后四道题来自于周日的hihocoder offer收割赛第九场. 我建了个群:欢迎加入qscoj交流群,群号码:540667432 大概作为 ...

  4. 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&源码(A.水+暴力,B.dp+栈)

    A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05   最后更新: 2017年2月21日 20:06   时间限制: 1000ms   内存限制: 128M 描述 传说喵哈哈村有三种神 ...

  5. 喵哈哈村的魔法考试 Round #19 (Div.2) 题解

    题解: 喵哈哈村的魔力源泉(1) 题解:签到题. 代码: #include<bits/stdc++.h> using namespace std; int main(){ long lon ...

  6. 喵哈哈村的魔法考试 Round #14 (Div.2) 题解

    喵哈哈村的四月半活动(一) 题解: 唯一的case,就是两边长度一样的时候,第三边只有一种情况. #include <iostream> #include <cstdio> # ...

  7. 喵哈哈村的魔法考试 Round #4 (Div.2) 题解

    有任何疑问,可以加我QQ:475517977进行讨论. A 喵哈哈村的嘟嘟熊魔法(1) 题解 这道题我们只要倒着来做就可以了,因为交换杯子是可逆的,我们倒着去模拟一遍就好了. 有个函数叫做swap(a ...

  8. 喵哈哈村的魔法考试 Round #20 (Div.2) 题解

    题解: A 喵哈哈村的跳棋比赛 题解:其实我们要理解题意就好了,画画图看看这个题意.x<y,那么就交换:x>y,那么x=x%y. 如果我们经过很多次,或者y<=0了,那么就会无限循环 ...

  9. 喵哈哈村的魔法考试 Round #18 (Div.2) 题解

    喵哈哈村的古怪石碑(一) 题解:暴力check一下是等比数列还是等差数列,然后输出答案即可.注意如果数据范围是1e9的话,就要快速幂了. 代码: #include <cstdio> #in ...

随机推荐

  1. select 不要 用*

    背景 说实在的,这有什么好记录的呢.记录这个有啥用,真是技术人员的吹毛求疵.说起来,就是给人装有用吧.既然记录了,也想个相关的段子吧.曾经有个同事写了个sql,效率极差,来了个女同事,竟然解决了,问题 ...

  2. LeetCode(48):旋转图像

    Medium! 题目描述: 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转 ...

  3. java.util.Random 类

    //: object/ForEachFloat.java package object; import java.util.Random; public class ForEachFloat { pu ...

  4. PHP中嵌套函数被调用时出现报错的问题

    对于初入门的PHP新手来说,在学习关于PHP函数嵌套的知识点时可能会有一定的难度.比如有的朋友在练习PHP函数嵌套相关问题时,会遇到调用内部函数时就会出现报错的情况等. 那么本篇文章就为大家详细得分析 ...

  5. (无)webservice执行过程深入理解

    前面我们搞了1,2个DEMO,基本对webservice服务发布,调用 ,执行 有一定的了解. 今天的话,我们再系统的梳理下webservice执行过程. 首先我们在webservice服务器端开发w ...

  6. IntelliJ IDEA快捷键:Ctrl+Alt+B

    To navigate to the implementation(s) of an abstract method,position the caret at its usage or its na ...

  7. poj 1751 输出MST中新加入的边

    给出结点的坐标 以及已建好的边 要输出MST中加入的边(已建好的边就不用输出了)结点的编号从1开始注意这题只有一组数据 不能用多组输入 否则就超时(在这被坑惨了Orz) Sample Input 91 ...

  8. 华为交换机SNMP OID

    http://vbb.fyjy.net:88/showthread.php?t=4647

  9. AOJ 0525 Osenbei【穷竭搜索】

    AOJ 0525 题意: 有一个烤饼器可以烤r行c列的煎饼,煎饼可以正面朝上(用1表示)也可以背面朝上(用0表示).一次可将同一行或同一列的煎饼全部翻转.现在需要把尽可能多的煎饼翻成正面朝上,问最多能 ...

  10. asp.net core 支付宝支付( 电脑2.0)

    支付宝电脑支付实测在手机浏览器也可以唤醒手机支付宝进行支付,因此也可以作为支付宝手机web支付方式.支付宝电脑支付流程为使用支付宝官方sdk通过获取的支付宝参数构造DefaultAopClient实例 ...