教主的花园 (Standard IO)

Time Limits: 1000 ms  Memory Limits: 65536KB

Goto ProblemSet

Description

【问题背景】
LHX教主最近总困扰于前来膜拜他的人太多了,所以他给他的花园加上了一道屏障。

【问题描述】
  可以把教主的花园附近区域抽像成一个正方形网格组成的网络,每个网格都对应了一个坐标(均为整数,有可能为负),若两个网格(x1, y1),(x2, y2)有|x1 – x2| +|y1 – y2| = 1,则说这两个网格是相邻的,否则不是相邻的。
  教主在y = 0处整条直线上的网格设置了一道屏障,即所有坐标为(x, 0)的网格。当然,他还要解决他自己与内部人员的进出问题,这样教主设置了N个入口a1, a2, …,aN可供进出,即对于y = 0上的所有网格,只有 (a1, 0),(a2, 0), ……, (aN, 0)可以通过,之外的所有纵坐标为0的网格均不能通过,而对于(x,y)有y不为0的网格可以认为是随意通过的。
  现在教主想知道,给定M个点对(x1, y1),(x2, y2),并且这些点均不在屏障上,询问从一个点走到另一个点最短距离是多少,每次只能从一个格子走到相邻的格子。

Input

  输入的第1行为一个正整数N,为屏障上入口的个数。
  第2行有N个整数,a1, a2, …, aN,之间用空格隔开,为这N个入口的横坐标。
  第3行为一个正整数M,表示了M个询问。
  接下来M行,每行4个整数x1, y1, x2, y2,有y1与y2均不等于0,表示了一个询问从(x1,y1)到(x2, y2)的最短路。

Output

  输出共包含m行,第i行对于第i个询问输出从(x1, y1)到(x2, y2)的最短路距离是多少。

Sample Input

2
2 -1
2
0 1 0 -1
1 1 2 2

Sample Output

4
2

Data Constraint

Hint

【数据规模】
  对于20%的数据,有n,m≤10,ai,xi,yi绝对值不超过100;
  对于40%的数据,有n,m≤100,ai,xi,yi绝对值不超过1000;
  对于60%的数据,有n,m≤1000,ai,xi,yi绝对值不超过100000;
  对于100%的数据,有n,m≤100000,ai,xi,yi绝对值不超过100000000。

对于这题,我爆零了……原因后话;

易证得:在x轴同侧,可以直接到达(即(y1<0&&y2<0)||(y1>0&&y2>0))【我将y1、y2打成x1、x2】,而异侧时,若在x轴上x1~x2(设x1<x2)间有入口,则可直接到达,而没有时,在[x1,x2]以外选取一个最优的门通过。

若是直接枚举门,n≤100000,会超时,于是乎可以排序后用二分求解。

注,虽然ai,xi,yi绝对值不超过100000000,但是想减后会爆int(longint),要用longlong(int64)

教主泡嫦娥 (Standard IO)

Time Limits: 1000 ms  Memory Limits: 65536KB

Goto ProblemSet

Description

【问题背景】
2012年12月21日下午3点14分35秒,全世界各国的总统以及领导人都已经汇聚在中国的方舟上。
  但也有很多百姓平民想搭乘方舟,毕竟他们不想就这么离开世界,所以他们决定要么登上方舟,要么毁掉方舟。

LHX教主听说了这件事之后,果断扔掉了手中的船票。在地球即将毁灭的那一霎那,教主自制了一个小型火箭,奔向了月球……

  教主登上月球之后才发现,他的女朋友忘记带到月球了,为此他哭了一个月。
  但细心的教主立马想起了小学学过的一篇课文,叫做《嫦娥奔月》,于是教主决定,让嫦娥做自己的新任女友。

【题目描述】
  教主拿出他最新研制的LHX(Let's be Happy Xixi*^__^*)卫星定位系统,轻松地定位到了广寒宫的位置。
  见到嫦娥之后,教主用温柔而犀利的目光瞬间迷倒了嫦娥,但嫦娥也想考验一下教主。
  嫦娥对教主说:“看到那边的环形山了么?你从上面那个环走一圈我就答应你~”

  教主用LHX卫星定位系统查看了环形山的地形,环形山上一共有N个可以识别的落脚点,以顺时针1~N编号。每个落脚点都有一个海拔,相邻的落脚点海拔不同(第1个和第N个相邻)。
  教主可以选择从任意一个落脚点开始,顺时针或者逆时针走,每次走到一个相邻的落脚点,并且最后回到这个落脚点。
  教主在任意时刻,都会有“上升”、“下降”两种状态的其中一种。

  当教主从第i个落脚点,走到第j个落脚点的时候(i和j相邻)
j的海拔高于i的海拔:如果教主处于上升状态,教主需要耗费两段高度差的绝对值的体力;否则耗费高度差平方的体力。
j的海拔低于i的海拔:如果教主处于下降状态,教主需要耗费两段高度差的绝对值的体力;否则耗费高度差平方的体力。

  当然,教主可以在到达一个落脚点的时候,选择切换自己的状态(上升→下降,下降→上升),每次切换需要耗费M点的体力。在起点的时候,教主可以自行选择状态并且不算切换状态,也就是说刚开始教主可以选择任意状态并且不耗费体力。

  教主希望花费最少的体力,让嫦娥成为自己的女朋友。

Input

  输入的第一行为两个正整数N与M,即落脚点的个数与切换状态所消耗的体力。
  接下来一行包含空格隔开的N个正整数,表示了每个落脚点的高度,题目保证了相邻落脚点高度不相同。

Output

  输出仅包含一个正整数,即教主走一圈所需消耗的最小体力值。
  注意:C++选手建议使用cout输出long long类型整数。

Sample Input

6 7
4 2 6 2 5 6

Sample Output

27

Data Constraint

Hint

【样例说明】
  从第3个落脚点开始以下降状态向前走,并在第4个落脚点时切换为上升状态。
  这样共耗费4 +(7)+3+1+2^2+2^2+4=27点体力。

【数据规模】
  对于10%的数据,N ≤ 10;
  对于30%的数据,N ≤ 100,a[i] ≤ 1000;
  对于50%的数据,N ≤ 1000,a[i] ≤ 100000;
  对于100%的数据,N ≤ 10000,a[i] ≤ 1000000,M ≤ 1000000000;

对于这题,我用了卡时……(直接暴力dp只有50points)

先讲暴力dp:用f【i】【j】表示到第i座山状态为j(0为上升,1为下降),这时可暴力枚举起点,按题目所说的去转移:

A[i]>a[i+1]:F[i+1][0]=min(f[i][1]+a[i]-a[i+1]+m,f[i][0]+sqr(a[i]-a[i+1]));

F[i+1][1]=min(f[i][1]+a[i]-a[i+1],f[i][0]+sqr(a[i]-a[i+1]+m));

A[i]<a[i+1]同理

时间复杂度为n^2,而且是longlong进行运算,会很慢,由于数据很水,可以用卡时,

保险起见也可用随机算法,随机起点,多次随机后形成拟正解。

测试时有人用倍增过了,在此说说,

可以明显得出,状态s[i,j]与状态s[j,k]可以分开处理,然后合起来就为状态s[I,k],由于n≤10000,直接枚举会超时+爆空间,因此可以预处理s[I,j]表示从i座山出发到包括它后第2^j座山的最优解,因为有上升下降之分,要再嵌一个b数组记录方向。复杂度为nlogn

此处讲讲o(n)的思路:

一种比较难以解释的:有人只从最高点和最低点分别做dp求最优解输出就过了……

附题解:正确的做法是使用三维动规:
f[i][j][k]表示第i个点的状态是j,并且有1号点状态为k推出的最小代价。

第二个点需要特殊处理:
if(tall[2]>tall[1])
{
f[2][0][0]=tall[2]-tall[1];
f[2][1][0]=tall[2]-tall[1]+M;
f[2][0][1]=sqr(tall[2]-tall[1])+M;
f[2][1][1]=sqr(tall[2]-tall[1]);

偶看

}
else
{
f[2][0][0]=sqr(tall[1]-tall[2]);
f[2][0][1]=tall[1]-tall[2]+M;
f[2][1][0]=sqr(tall[1]-tall[2])+M;
f[2][1][1]=tall[1]-tall[2];
}

转移就是(tall[i]>tall[i-1])
f[i][0][0]=min(f[i-1][0][0]+tall[i]-tall[i-1],f[i-1][1][0]+sqr(tall[i]-tall[i-1])+M);
f[i][1][0]=min(f[i-1][0][0]+tall[i]-tall[i-1]+M,f[i-1][1][0]+sqr(tall[i]-tall[i-1]));
f[i][0][1]=min(f[i-1][0][1]+tall[i]-tall[i-1],f[i-1][1][1]+sqr(tall[i]-tall[i-1])+M);
f[i][1][1]=min(f[i-1][0][1]+tall[i]-tall[i-1]+M,f[i-1][1][1]+sqr(tall[i]-tall[i-1]));

对于tall[i]<tall[i-1]这种情况以及逆时针的情况类似。
注意:顺时针推用的数组是f,逆时针推用的数组是g。
然后枚举每一个落脚点作为起始点,哪么从他开始绕一圈的代价就是
for(int i=2;i<=N;i++)
for(int j=0;j<=1;j++)
for(int k=0;k<=1;k++)
for(int m=0;m<=1;m++)
for(int n=0;n<=1;n++)
if(n==k) Min=min(Min,f[i][j][k]+g[N-i+2][m][n]+M);
    elseMin=min(Min,f[i][j][k]+g[N-i+2][m][n]);

这样时间复杂度是O(n)的

保镖排队 (Standard IO)

Time Limits: 1000 ms  Memory Limits: 65536KB

Goto ProblemSet

Description

【问题背景】
  教主LHX作为知名人物,时刻会有恐怖分子威胁他的生命。于是教主雇佣了一些保镖来保障他的人生安全。

【题目描述】
  教主一共雇佣了N个保镖,编号为1~N。每个保镖虽然身手敏捷武功高强,但是他在其余N-1个保镖里,都会有一个“上司”,他会对他的上司言听计从。但一号保镖例外,他武功盖世,不惧怕其余任何保镖,所以他没有上司。
  教主LHX会对这N个保镖进行定期视察。每次视察的时候,首先会让所有保镖排队。
  对于每个保镖,在他心目中会对他的所有下属的武功实力排个队。
  现在教主要求排出来的队伍满足:①互为上司-下属的两个保镖,上司在前,下属在后②对于一个保镖的所有下属,武功实力较强的在前,较弱的在后。
  教主想知道,总的排队方法数除以10007的余数是多少。

Input

  输入的第一行为一个正整数T,表示了数据组数。
  对于每组数据:
  第一行为一个正整数N。
  接下来N行,每行描述一个保镖。
  第i+1行,会有一个整数K,代表第i个保镖的下属个数,接下来K个数,代表第i个保镖的下属按照武功实力从高到低的编号。

Output

  输出包括C行,每行对于每组数据输出方案数mod 10007后的结果。

Sample Input

2
5
2 2 3
2 4 5
0
0
0
7
2 2 3
2 4 5
2 6 7
0
0
0
0

Sample Output

3
10

Data Constraint

Hint

【样例说明】
  对于第1组数据,有以下3种排列是合法的:
1 2 4 3 5
1 2 3 4 5
1 2 4 5 3
  同时满足了1在2与3之前且2在3之前,2在4与5之前且4在5之前

【数据规模】
  对于20%的数据,有N ≤ 9;
  对于40%的数据,有对于所有K,有K ≤ 2;
  对于60%的数据,有N ≤ 100;
  对于100%的数据,有T ≤ 10,N ≤ 1000,K ≤ N。

对于这题我们可以将其转化成一棵树,按题意所说的,就是将等级高的放在等级低的前面,这样我们可以先做等级低的,然后与稍高的合并(这样可以将较高的放在首位,确保较高的在较低的前面),再做等级高的:

对于第i个点,设排列数为f[i],其后继为a[j](前面的等级低于后面的),b【i】记录以节点i为根的树的节点数

则有:f[i]=f[i]*f[a[j]]*C(b[a[j]],y+b[a[j]]);(y记录已处理的后继树节点总数)

附代码:

#include<iostream>

#include<cstdio>

#include<algorithm>

intm,t,n,x,sum,y,ans,mod;

int g[10001],a[10001][2],b[10001],f[1001][1001];

voidin(int x,int y){

a[++sum][0]=y;

a[sum][1]=g[x];

g[x]=sum;

}

voidinit(){

sum=0;

scanf("%d",&n);

for (int i=1;i<=n;i++){

scanf("%d",&x);

b[i]=1;

g[i]=0;

for (int j=1;j<=x;j++){

scanf("%d",&y);

in(i,y);

}

}

}

intdfs(int x){

int i=g[x];

int s=1;

int y=0;

while (i!=0){

s=(s*dfs(a[i][0]))%mod*f[y+b[a[i][0]]-1][b[a[i][0]]-1]%mod;

y+=b[a[i][0]];

b[x]+=b[a[i][0]];

i=a[i][1];

}

return(s);

}

voidwork(){

ans=dfs(1);

printf("%d\n",ans);

}

intmain(){

freopen("3.in","r",stdin);

freopen("3.out","w",stdout);

scanf("%d",&t);

mod=10007;

f[0][0]=1;

for (int i=1;i<=1000;i++){

f[i][0]=1;

for (int j=1;j<=i;j++)

f[i][j]=(f[i-1][j]+f[i-1][j-1])%mod;

}

for (int i=1;i<=t;i++){

init();

work();

}

return0;

}

教主的别墅 (Standard IO)

Time Limits: 1000 ms  Memory Limits: 65536KB

Goto ProblemSet

Description

【题目背景】
LHX教主身为宇宙第一富翁,拥有一栋富丽堂皇的别墅,由于别墅实在太大了,于是教主雇佣了许许多多的人来负责别墅的卫生工作,我们不妨称这些人为LHXee。

【题目描述】
  教主一共雇佣了N个LHXee,这些LHXee有男有女。
  教主的大别墅一共有M个房间,现在所有的LHXee在教主面前排成了一排。教主要把N个LHXee分成恰好M个部分,每个部分在队列中都是连续的一段,然后分别去打扫M个房间。
  教主身为全世界知识最渊博的人,他当然知道男女搭配干活不累的道理,以及狼多羊少,羊多狼少的危害之大。所以教主希望一个分配方式,使得所有小组男女个数差的最大值最小。
  教主还希望你输出从左到右,每个组的人数。
  如果有多种人数组合都能达到最优值,教主希望你分别告诉他这些方案中字典序最小和最大的方案。换句话说,你需要找到两种方案,这两种方案满足所有组男女个数差最大值最小的前提下,第一种方案(字典序最小)要越靠前的组人数越少,也就是让第一个小组人尽量少,并且在第一个小组人尽量少的前提下,让第二个小组的人尽量少,依此类推;第二种方案(字典序最大)则要让越靠前的组人数越多。

Input

  输入的第1行为两个正整数N与M,用空格分隔。
  第2行包含一个长度为N的串,仅由字符组成,第i个字符为0表示在这个位置上的LHXee为女生,若为1则为男生。

Output

  输出文件包含两行,每行M个正整数,正整数之间用空格隔开,行末无多余空格。这M个正整数从左到右描述了你所分的每个组的人数。
  第1行为字典序最小的方案,第2行为字典序最大的方案。

Sample Input

8 3
11001100

Sample Output

1 2 5
5 2 1

Data Constraint

Hint

【样例说明】
  字典序最小的方案按1, 10, 01100分组,每组男女个数差的最大值为1,为最小。
  字典序最大的方案按11001, 10, 0分组。

【数据规模】
  对于40%的数据,有N ≤ 100;
  对于50%的数据,有N ≤ 1000;
  对于65%的数据,有N ≤ 100000;
  对于100%的数据,有N ≤ 5000000,M ≤ N且M ≤ 100000。

【提示】
关于字典序:
比较S1[N]与S2[N]的字典序大小,可以找到S1[N]与S2[N]中第1个不相同数字S1[i]与S2[i](即有对于所有1≤k<i,都有S1[k]=S2[k],但S1[i]≠S2[i])。如果S1[i]<S2[i],那么说S1[N]字典序比S2[N]小,否则说S1[N]字典序比S2[N]大。

若我们对于a[i],若a[i]=”1”,则b[i]=1;若a[i]=”0”,则b[i]=-1。将b数组前缀和后,易证:最优方案下,最大男女人数差ans=(abs(a[n])-1)/m+1(即上取整),而对于a[n]=0时要特判:将b数组中0看做挡板,若分割的区间数不足m则ans=1,反之为0,

此时已知最大男女人数差,即可贪心出解:

这里讲第一问(第二问就是倒着做):设l为上次分组最后一个人的位置+1,即这次分组的开始,i为枚举到第i人,若有((abs(b[i]-b[l-1])>=ans)&&(abs(b[n]-b[i])>=ans))则可以分组i-l+1人,到第m-1组建立好时,剩余人数即第m组

附程序:

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<cmath>

usingnamespace std;

int l,n,m,ans,x;

chars[5000200];

intc[100001],a[5000200];

intdid(int x,int y){

if (x==0)return(0);

return((x-1)/y+1);

}

intmain(){

freopen("4.in","r",stdin);

freopen("4.out","w",stdout);

scanf("%d %d\n",&n,&m);

scanf("%s",s);

for (int i=0;i<=n-1;i++){

a[i+1]=a[i];

if (s[i]=='1')a[i+1]++;elsea[i+1]--;

}

if (a[n]==0){

l=0;

for (int i=1;i<=n;i++)if(a[i]==0)l++;

if (l>=m-1)ans=0;else

ans=1;

}else

ans=(abs(a[n])-1)/m+1;

l=0;

x=0;

for (int i=1;i<=n;i++){

if((abs(a[i]-a[l])<=ans)&&(did(abs(a[n]-a[i]),m-x-1)<=ans)){

printf("%d",i-l);

x++;

l=i;

if (x==m-1){

printf("%d\n",n-i);

break;

}

}

}

l=n;

x=0;

for (int i=n;i>=1;i--)

if((abs(a[l]-a[i-1])<=ans)&&(did(abs(a[i-1]),m-x-1)<=ans)){

x++;

c[m-x+1]=l-i+1;

l=i-1;

if (x==m-1){

c[1]=i-1;

break;

}

}

for (int i=1;i<=m-1;i++)

printf("%d ",c[i]);

printf("%d\n",c[m]);

return 0;

}

jzojNOIP2014模拟 8.14总结相关推荐

  1. [模拟] leetcode 14 最长公共前缀

    [模拟] leetcode 14 最长公共前缀 1.题目 题目链接 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例1: 输入: [& ...

  2. Cisco PT模拟实验(14) 路由器OSPF动态路由的配置

    Cisco PT模拟实验(14) 路由器OSPF动态路由的配置 实验目的: 掌握OSPF动态路由选择协议的配置方法 掌握路由选择表中的OSPF路由描述 熟悉路由选择和分组转发的原理及过程 实验背景: ...

  3. JZOJ.5274【NOIP2017模拟8.14】数组

    Description Input Output Sample Input 输入样例1: 3 2 7 5 4 2输入样例2: 5 3 1 5 4 3 5 5 Sample Output 输出样例1: ...

  4. JZOJ 3769. 【NOI2015模拟8.14】A+B

    Description 对于每个数字x,我们总可以把它表示成一些斐波拉切数字之和,比如8 = 5 + 3, 而22 = 21 + 1,因此我们可以写成 x = a1 * Fib1 + a2 * Fib ...

  5. JZOJ 100047. 【NOIP2017提高A组模拟7.14】基因变异

    Description 21 世纪是生物学的世纪,以遗传与进化为代表的现代生物理论越来越多的 进入了我们的视野. 如同大家所熟知的,基因是遗传因子,它记录了生命的基本构造和性能. 因此生物进化与基因的 ...

  6. JZOJ 100046. 【NOIP2017提高A组模拟7.14】收集卡片

    Description Star 计划订购一本将要发行的周刊杂志,但他可不是为了读书,而是-- 集卡. 已知杂志将要发行 N 周(也就是 N 期),每期都会附赠一张卡片.Star 通 过种种途径,了解 ...

  7. jzoj5365-[GDOI2018模拟9.14]通信【线段树合并】

    正题 题目大意 nnn个节点的一棵树,随机选择一个区间,求这个区间的点所构成的虚树的期望权值和. 解题思路 考虑每一条边的贡献,定义一边的点为黑点,一边的为白点,显然包含黑白的区间都会产生贡献.考虑减 ...

  8. jzoj5363-[NOIP2017提高A组模拟9.14]生命之树【启发式合并,Trie】

    正题 题目大意 nnn个点的一棵树,每个节点有一个值valvalval和一个字符串SSS.对于每个点求∑x∈decp∑y∈decp(x<y)(valxxorvaly)∗∣LCP(Sx,Sy)∣\ ...

  9. NOIP模拟测试14「旋转子段·走格子·柱状图」

    旋转子段 连60分都没想,考试一直肝t3,t2,没想到t1最简单 我一直以为t1很难,看了题解发现也就那样 题解 性质1 一个包含a[i]旋转区间值域范围最多为min(a[i],i)----max(a ...

最新文章

  1. Java 8中一些常用的全新的函数式接口
  2. random.choice()使用
  3. Ubuntu12.04 VMware Tools的安装
  4. 谈谈我对Spring IOC的理解
  5. 中石油训练赛 - Isomorphic Inversion(哈希+贪心)
  6. 常用SQL语句(增删查改、合并统计、模糊搜索)
  7. 程序员:凭什么他大专12K,而我硕士研究生才5K?
  8. Suse发生了错误Access denied for user #39;#39;@#39;localhost#39; toamp;
  9. win11快捷键失效怎么处理 Windows快捷键失效的解决方法
  10. Python笔记-OpenCV图像处理和人脸识别
  11. SmartImageView
  12. 数据仓库--事实表和维度表
  13. 科技时代:继刷脸支付之后,无感停车成新热点
  14. C#、Asp.net byte转换为GB/MB/KB 方法
  15. 手机html 横向全屏,移动端强制全屏和横竖屏
  16. 帝国cms配置php,帝国cms如何安装
  17. 流媒体选择Nginx是福还是祸?
  18. woj 1537 Stones I
  19. React的Render的简单实现
  20. mysql难不难_mysql数据库难学吗?

热门文章

  1. Ambarella : 一家伟大的视频压缩处理芯片厂商
  2. Gabor滤波器学习
  3. 程序实现汉字转换为拼音
  4. 移动端H5页面必用代码
  5. PCB制造常用的13种测试方法,你了解几种?
  6. 如何用科学的方法,保障数据准确性
  7. (python热门库之)PyQt5常用代码
  8. java基础 day12-FileInputStream类,文件的复制,缓冲流,Propertes文件,xml文件读写,网络socket编程(构建TCP客户端),内部类
  9. 使用AWK和XARGS为文件批量改名
  10. zip压缩包解压中文乱码问题