Noip模拟 Day6.12
第一题:贪吃蛇(snake)
本题其实就是判断一个有向图中有没有环,做一次拓扑排序就可以了,如果所有点都入队了,就表示没有环,否则就有环。或者就是dfs一次,每个点只需要被访问一次,这样也是O(n)的。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std; #define N 1000010 struct edge
{
int next,to;
}e[N<<1];
int head[N<<1];
int cnt; int n,m,T;
int u,v; int flag;
int vis[N<<1],f[N<<1]; void link(int x,int y)
{
e[++cnt]=(edge){head[x],y};
head[x]=cnt;
} void dfs(int x,int i)
{
if (f[i])
{
flag=1;
return ;
}
if (vis[i])
return ;
f[i]=1;
vis[i]=1;
int t=head[i];
while (t)
{
dfs(x,e[t].to);
if (flag)
break;
t=e[t].next;
}
f[i]=0;
} int main()
{
freopen("snake.in","r",stdin);freopen("snake.out","w",stdout);
scanf("%d",&T);
while (T--)
{
memset(f,0,sizeof(f));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
flag=0;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
scanf("%d%d",&u,&v),link(u,v);
for (int i=1;i<=n;i++)
{
if (!vis[i])
dfs(i,i);
if (flag)
break;
}
if (flag)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}
第二题:营养计划(egg)
本题可以使用递推方法解决,应用堆积木的思想。
记f[i,j]为将i个鸡蛋分j天的方案总数
由于方案与顺序无关,那么每次考虑怎么处理给最少鸡蛋的那天,
给最少的那天再加上一个,每一天就都要加上一个;或者最少的那天不再加了,就继续将i个鸡蛋分j-1天即可。
即:f[i,j]=f[i-j,j]+f[i,j-1]
边界:f[i,0]=1
那么ans=f[n,m]
本题需要取模,因为加法是满足a mod mo+b mod mo=(a+b) mod mo的,所以直接加一下模一下就可以了。
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; #define MOD 19940714
#define N 2010 int n,m;
int ans; int f[N<<1][N<<1]; int main()
{
freopen("egg.in","r",stdin);freopen("egg.out","w",stdout);
scanf("%d%d",&n,&m);
f[0][0]=1;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
f[i][j]=(f[i-1][j-1]+f[i][j-i])%MOD;
for (int i=1;i<=m;i++)
ans=(ans+f[i][n])%MOD;
printf("%d\n",ans);
return 0;
}
第三题:购物狂人(shopping)
本题是简单数据结构的应用。
由于每个商店只会被算一次,而且本题中的操作是区间型的,那么可以考虑使用链表或类似并查集的方法来做到对所有操作均摊O(1)的时间复杂度。
类似并查集的方法,记f[i]为i这个商店所在的连续的这一段已被覆盖过的商店的最右边的那个,对于每次操作,将L~R这一段都并入R所在的集合即可。可是答案怎么统计呢?其实可以就用一个布尔数组存每个商店有没被覆盖过,在将指针扫过L~R时,顺便统计一下连续的若干段的平方和加进答案即可。
其实,本题也是可以用线段树做的,方法略微复杂一点
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; typedef long long LL; #define N 300010 LL n,m;
LL l,r;
LL ans; LL f[N],b[N]; int find(LL x)
{
return x==f[x] ? f[x] : f[x]=find(f[x]);
} int main()
{
freopen("shopping.in","r",stdin);freopen("shopping.out","w",stdout);
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n+1;i++)
f[i]=i;
for (int i=1;i<=m;i++)
{
scanf("%lld%lld",&l,&r);
LL j=find(l),k=0;
while (j<=r)
{
if (!b[j])
k++,b[j]=1,f[j]=r,j++;
else
ans+=(k*k),k=0,f[j]=r,j++;
j=find(j);
}
ans+=(k*k);
}
printf("%lld",ans);
return 0;
}
第四题:精彩比赛(match)
本题的题目描述相当繁琐,但关键信息在规定2,要求取第一组的连续的几个人和第二组的连续几个人之间的所有比赛,如果记g[i,j]表示第一组的i号选手和第二组的j号选手之间的比赛关注度(没比赛就是0),容易想到本题其实就是求一个矩阵g的最大子矩阵。
至于最大子矩阵的求法,这里介绍一种O(n^3)的算法
记f[i,j,k]为前i行第j~k列的最大子矩阵(第i行必须选),s[i,j]=sigma(g[i,1]~g[i,j])
有f[i,j,k]=max{f[i-1,j,k],0}+s[i,k]-s[i,j-1]
那么ans=max{f[i,j,k]}
至于空间的话,可以使用滚动数组把空间复杂度优化到O(n^2)
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std; typedef long long LL; #define N 310 int n,m;
int x,y,w; LL ans; LL sum[N];
int g[N][N]; int main()
{
freopen("match.in","r",stdin);freopen("match.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&w),g[x][y]+=w;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
sum[j]=g[i][j];
for (int j=i+1;j<=n;j++)
{
for (int k=1;k<=n;k++)
sum[k]+=g[j][k];
LL res=0;
for (int k=1;k<=n;k++)
{
res+=sum[k];
if (res<0)
res=0;
else
ans=max(ans,res);
}
}
}
printf("%lld\n",ans);
}
Noip模拟 Day6.12的更多相关文章
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- NOIP模拟赛12
期望得分:100+100+50=250 实际得分:100+100+30=230 A 约数之和(count.pas/c/cpp) TL:1S ML:128MB[Description]我们用 D(x)表 ...
- Noip模拟 Day6.13 By LD T1
一.哲哲回家 出题人的解答: 可以将其转化成最短路模型. 这个地方转车怎么转移有点困难,有两种方法: 1.我们可以再把每一个点拆成M个点,我们用F[i,j]表示从1号点到i这个点并且坐在j路车上的最少 ...
- 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」
164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...
- NOIP模拟测试12
T1 斐波那契 一道找规律题,被我做成了贼难的题. 观察图片可知x=f[i-1]+j.(j为x的父亲)且j<=f[i-1],然后就二分找父亲没了. #include<bits/stdc++ ...
- [NOIP模拟测试12]题解
A. 找规律题.儿子的编号减去 小于它编号的最大的fibonacci数 即可得到它父亲的编号. 然后两个节点都暴力上跳就好了.预处理一下fibonacci数,每次二分查找即可. #include< ...
随机推荐
- 记录一次通过命令行方式来使用svn碰到的一系列问题
由于使用Xcode自带的svn管理碰到很多问题,搞得头昏脑胀,找资料时看到小码哥这方面的视频,看完就开始折腾了. 准备:1.远程仓库地址及授权账号(用户名和密码) 2.一份项目代码,之所以要有这份代码 ...
- js页面文字选中后分享实现
var $sinaMiniBlogShare = function(eleShare, eleContainer) { var eleTitle = document.getElementsByTag ...
- margin负值应用
我理解的最关键的一点是: 在文档流中,只能是后面的流向前面的,即文档流只能向左或向上流动,不能向下或向右移动.第二个元素的基准线是第一个元素的右边界,第三个元素的基准线是第一.二个元素排好后最右边的边 ...
- Layui表格之动态添加数据(表格多选解决方案)
前言: Layui已经给出了多选记录的解决方案,是在每条数据的前面加上CheckBox,每次选择都有监听.效果是这样: 实现监听的代码如下,这是一种解决选择多条数据的方案: table.on('edi ...
- (十二)python3 迭代器
可以直接作用于 for 循环的对象统称为可迭代对象: Iterable .一类是集合数据类型,如 list . tuple . dict . set . str 等,一类是 generator ,包括 ...
- java 通过反射机制调用某个类的方法
package net.xsoftlab.baike; import java.lang.reflect.Method; public class TestReflect { public s ...
- [luoguP1013] 进制位(搜索)
传送门 纯搜索,无优化! #include <cstdio> #include <cstring> #include <iostream> #include < ...
- noip模拟赛 将军令
分析:对于前18个点可以考虑非常恶心的树形dp,不推荐这种方法.其实贪心还是很显然的.每个小队可以控制距离不超过k里的驿站,肯定要让这个k里不能白白浪费.对于所有叶子节点,如果它还没有被控制,那么肯定 ...
- hdu 5073 推公式相邻质心转换
#include<stdio.h> #include<stdlib.h> #include<string.h> #define N 51000 int cmp(co ...
- 关于android系统启动不同activity默认过渡动画不同的一些认识
在同一个android设备里,发现不同的app启动时显示的过渡动画是不同的.查看显示不同过渡动画的两个app的源码,其设置的主题都是同一个主题,但是为什么过渡动画效果不同呢?后来发现,activity ...