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< ...
随机推荐
- thinkphp5验证码处理
1.确定项目目录>vendor>topthink>think-captcha目录存在 2.在config中添加验证码配置 //验证码配置 'captcha' => [ // 验 ...
- appendHTML方法ajax加载更多评论实例页面
//在后添加 <script>var appendHTML = function(el, html) { var divTemp = document.createElement(&quo ...
- 杀了个回马枪,还是说说position:sticky吧
<style> article { max-width: 600px; margin: 1em auto; } article h4, article footer { position: ...
- linux下nginx、php和mysql安装配置
一.安装nginx 安装nginx yum install -y epel-release yum install nginx -y 查看nginx软件包包括了哪些文件 rpm -ql nginx 启 ...
- 将一个list中的元素的某一属性取出来单独放到一个list里面
有很多时候我们会遇到这样的场景,就是要将一个list中的某一个元素中的某一属性单独拿出来放在一个新的list里面,这中时候,我们就可以用以下的方法来进行实现: List<DTO> item ...
- Matlab学习笔记(二)
二.MATLAB基础知识 (二)数值.变量和表达式 命名规则: 变量名对大小写敏感,即区分大小写 变量名必须以字母开头,后面可以采用数字.下划线和字母,但不能使用空格.标点符号和运算符 变量名最长可以 ...
- Java 集合相关
对整个体系做一个记录,并不涉及详细应用 Object类 1. 重写toString方法 System.out.println可以打印任何对象在于Object类拥有一个方法 public String ...
- 对Spring框架的理解(转)
① spring框架是一个开源而轻量级的框架,是一个IOC和AOP容器 ② spring的核心就是控制反转(IOC)和面向切面编程(AOP) ③ 控制反转(IOC):是面向对象编程中的一种设计原则 ...
- Oracle on Azure
价格列表 https://azure.microsoft.com/en-us/marketplace/partners/msopentech/oracle-db-12c/ Oracle-Base 安装 ...
- C51 矩阵按键 个人笔记
矩阵按键 电路 每个按键一端和同行一端相连(JP4的高4位),另一端和同列一端相连(JP4的低4位) 判断按键是否按下: 法一:逐行扫描 for(int i = 8 ; i>3 ; i-- ) ...