NOIP 2017 Day1 解题报告
总分:100分
T1,小凯的疑惑, 100分
T2,时间复杂度,0分
T3,逛公园,0分
T1
###题意简化:
给定两个互质的数字,输出最大不能表示的数;
基础数论题目
代码:
#include<bits/stdc++.h>
using namespace std;
inline long long read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main()
{
long long a,b;
a=read(),b=read();
cout<<a*b-a-b;
return 0;
}
T2:
解题思路:
对于模拟题:学到了一点:模块化,尽量处理的时候分开,不然凑一起真炸的满天飞
1.就是输入的问题,输入t组数据肯定没有什么问题
2.输入循环体的时候,我在考试的时候选择了字符读入,然后我人傻了,不知道怎么做了,学长讲的那就是直接string code[105],然后就可以表示了,
3.对于第一个板块,也就是我们首先要处理的东西,那就是字符串中的数字,(代码中就是calc--计算器),这个确有巧妙,当时我因为字符读入,直接减去'0';
注:原来题目给定的时间复杂度一样这么求,只不过在前面进行稍微判别,函数名为 geto();
4.对于第二个板块,在进行我们主体部分,进行大模拟,模拟首先就是我们要考虑我们碰上'F'之后的事情
(1).我们肯定需要把这个循环的迭代器找出来也就是 code[i][2],我们直接以一个bool数组表示它是否已经用过了,如果用过,那么就是编译错误;
(2).我们将循环变量压入栈中,会发现,和括号的匹配很像
(3).我们用a,b取出i,j
如果 b<a ,那么没有进入循环。用一个 flag 来保存最早的没有没有进入的 k。
如果都进入了,则flag为-1。
如果 a<=b ,代表进入循环,此时若 b-a>1000 并且 flag 为 -1 ,则本层循环对复杂度有贡献,执行 now++ 操作。
同时我们用 ef[26] 保存 now++ 时 k的信息**(ef[k]=true)。(在k出栈时now - -,ef[k]=false)并更新res。(res=max(res,now))
5.那碰上‘E’呢
(1).首先我们看下栈,空,代表'F'已经没有了,但是‘E’还有,不匹配
(2).计算一下时间复杂度
(3).在最后的时候看一下‘F’有没有剩下;
经过九九八十一难,肝出来了,就是全力的模拟每一种情况,需要大量的耐心和清晰的头脑(我感觉我脑袋已经炸了)
#include<cstdio>
#include<stack>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxl=105;
int t,l,w;
string o;
string code[maxl];
int calc(int &x,string c)
{
int res=0;
int len=c.size();
while(c[x]<'0' || c[x]>'9'&&x<c.size()) {
if(c[x]=='n'){
++x;
return 1000000;
}
++x;
}
while(c[x]>='0' && c[x]<='9') {
res*=10;res+=c[x]-'0';
++x;
}
return res;
}
int geto() {
int res=0,x=3;
int len=o.size();
if(o[2]=='n') res=calc(x,o);
else res=0;
return res;
}
int check() {
int res=0,now=0;
int a,b,x;
stack<int> s;
int flag=-1;
bool ins[26]={0};
bool ef[26]={0};
for(int i=1;i<=l;i++) {
if(code[i][0]=='F') {
int k=code[i][2]-'a';
if(ins[k]) return -1;
s.push(k);ins[k]=true;
x=4;
a=calc(x,code[i]);b=calc(x,code[i]);
if(b-a>1000)
{
if(flag==-1)
{
now++;
res=max(res,now);
ef[k]=true;
}
}
if(a>b) {
if(flag==-1) flag=k;
}
}
if(code[i][0]=='E') {
if(s.empty()) return -1;
int k=s.top();
s.pop();ins[k]=false;
if(flag==k) flag=-1;
if(ef[k]) {
ef[k]=false;
now--;
}
}
}
if(s.size()) return -1;
return res;
}
int main() {
scanf("%d",&t);
while(t--) {
int ww;
scanf("%d ",&l); getline(cin,o);
w=geto();
for(int i=1;i<=l;i++) getline(cin,code[i]);
ww=check();
if(ww==-1) printf("ERR\n");
else {
if(ww==w) printf("Yes\n");
else printf("No\n");
}
}
}
T3:
题意简化:
一个有向无重边自环图,设D为从1号点走到n号点的最短距离。问有多少条从1到n的路径长度不超过D+K。K为给定的值,且K≤50,如果有无数条,输出-1
题意分析
首先看一下,k的取值,k≤50,就很容易想到DP,所以我们考虑一下,题目到底怎么DP
1. 对于正常的图来说,它怎么也不可能有无穷条最短路(我们假设k=0的时候),那么也就只有有0环的时候才会出现这种情况,
2.那么我们设一个二维数组 lh[u][x](轮回),表示 节点 U比最短路多出 x 的距离
注:除了0环,不可能相等,相等的时候那就是说明我们在上一个节点走到这的时候返回这个点,节省复杂度
3.然后我们就去寻找比最短路小 k的价值的答案(也就是边数)
4.那么我们也可以设一个二维数组 f[u][x]表示节点 i到 n走了x的多余价值,
5.然后就A掉了
然后发现不会:
那就暴力一下,数据很良心,给了k=0的情况,那就十分类似于[路径统计](https://www.luogu.com.cn/problem/P1608)。
之后我们就开始正解了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define inf 0x3f
using namespace std;
const int maxn=1e5+10;
struct node
{
int nxt, to,weath;
};
node edge1[maxn<<1],edge2[maxn<<1];
int head1[maxn<<1],head2[maxn<<1];
int number_edge1,number_edge2;
int n,m,k,p;
//===============正反建图=================
void add1(int from,int to,int weath)
{
number_edge1++;
edge1[number_edge1].nxt=head1[from];
edge1[number_edge1].to=to;
edge1[number_edge1].weath=weath;
head1[from]=number_edge1;
}
void add2(int from,int to,int weath)
{
number_edge2++;
edge2[number_edge2].nxt=head2[from];
edge2[number_edge2].to=to;
edge2[number_edge2].weath=weath;
head2[from]=number_edge2;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//=======标准spfa=========
int dis[maxn],vis[maxn];
queue<int> q;
void spfa(int x)//标准spfa
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[x]=0;
//vis[x]=1;
q.push(x);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head2[u];i;i=edge2[i].nxt)
{
int v=edge2[i].to;
if(dis[v]>dis[u]+edge2[i].weath)
{
dis[v]=dis[u]+edge2[i].weath;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
//出现了无穷条,意味着出现了0环,那么标记一下,用的数组 lh(轮回)
int lh[maxn<<1][60],f[maxn<<1][60];
//lh的右数组为什么开60,因为出现0环,在这个环上,无论那一个点,哪一种情况都将是 j的距离
//f[i][j]表示 从i号点到 n号点走了 j的多余路径
//=================寻找路径==============
int dfs(int u,int x)
{
if(lh[u][x]==2) return f[u][x];//从别的点出发到达了这个点,
if(lh[u][x]==1) return -1;
lh[u][x]=1;
for(int i=head1[u];i;i=edge1[i].nxt)
{
int v=edge1[i].to;
int w=x-(dis[v]+edge1[i].weath-dis[u]);
if(w<0 || w>k) continue;
int val=dfs(v,w);
if(val==-1) return -1;//有0环
f[u][x]+=val;
f[u][x]%=p;
}
lh[u][x]=2;
return f[u][x];
}
int main()
{
int t=read();
while(t--)
{
memset(head1,0,sizeof(head1));
number_edge1=0;
memset(head2,0,sizeof(head2));
number_edge2=0;
memset(lh,0,sizeof(lh));
memset(f,0,sizeof(f));
n=read(),m=read(),k=read(),p=read();
for(int i=1;i<=m;i++)
{
int u=read(),v=read(),w=read();
add1(u,v,w);
add2(v,u,w);
}
spfa(n);
f[n][0]=1;
int ans=0;
for(int i=0;i<=k;i++)
{
int judge=dfs(1,i);
if(judge==-1)
{
ans=-1;
}
else
{
ans+=judge;
ans%=p;
}
}
printf("%d\n",ans);
}
return 0;
}
最后的总结:
对于任何一道题来说,如果不会,先放一下,看一下后面的题是否可以做,拿部分分也是可以的,T2模拟模拟不出来却非要一直模拟,结果,T3就只有30分钟的时间,最后还编译出错了。
NOIP 2017 Day1 解题报告的更多相关文章
- 学大伟业Day1解题报告
学大伟业Day1解题报告 张炳琪 一. 时间分配 T1:30分钟 T2: 60分钟 T3:100分钟 二.答题情况及错因 T1:100 T2:55 T3 ...
- CH Round #54 - Streaming #5 (NOIP模拟赛Day1)解题报告
最近参加了很多CH上的比赛呢~Rating--了..题目各种跪烂.各种膜拜大神OTZZZ T1珠 描述 萌蛋有n颗珠子,每一颗珠子都写有一个数字.萌蛋把它们用线串成了环.我们称一个数字串是有趣的,当且 ...
- 2017.9.17校内noip模拟赛解题报告
预计分数:100+60+60=220 实际分数:100+60+40=200 除了暴力什么都不会的我..... T1 2017.9.17巧克力棒(chocolate) 巧克力棒(chocolate)Ti ...
- 2017.7.15清北夏令营精英班Day1解题报告
成绩: 预计分数:20+10+40 实际分数:100+10+40. 一百三十多人的比赛全场rand7还水了个鼠标+键盘 unbelievable! 考试题目链接: https://www.luogu. ...
- [雅礼NOIP集训 2017] number 解题报告 (组合数+二分)
题解: 令$S(i)={i+1,i+2,...,i<<1}$,f(i,k)表示S(i)中在二进制下恰好有k个1的数的个数 那么我们有$f(i,k)=\sum_{x=1}^{min(k,p) ...
- NOIP2018提高组Day1 解题报告
前言 关于\(NOIP2018\),详见此博客:NOIP2018学军中学游记(11.09~11.11). 这次\(NOIP\ Day1\)的题目听说很简单(毕竟是三道原题),然而我\(T3\)依然悲剧 ...
- 常州培训 day1 解题报告
第一题:(骗分容易,AC难.) 题目大意: 给出一个字符串,找出满足条件A的区间的个数.A:字符A,B,C的出现次数相同. 都出现0次也算,区间的长度可以是0(就是只有一个数).30% |S| ≤ 1 ...
- 2017 SCNUCPC 解题报告
校内赛题目.解题思路.参考代码一览 A. Blackstorm's Blackstore Problem Description Blackstorm is going to open a black ...
- NOIP 2018 D1 解题报告(Day_1)
总分 205分 T1 100分 T2 95分 T3 10分 T1: 题目描述 春春是一名道路工程师,负责铺设一条长度为 nn 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 ...
随机推荐
- PageObject课程培训记录
前言 昨晚的培训课程讲了PO设计模式,对于PO模式我们需要去了解关于为什么要使用PO,而不使用PO是什么情况?什么是PO模式?PO怎么去使用? 第一,为什么要使用PO,而不使用PO是什么情况? 我们先 ...
- 【小白学PyTorch】19 TF2模型的存储与载入
[新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx64501661 ...
- matlab中num2str 将数字转换为字符数组
参考:https://ww2.mathworks.cn/help/matlab/ref/num2str.html?searchHighlight=num2str&s_tid=doc_srcht ...
- matlab中reshape 重构数组
来源:https://ww2.mathworks.cn/help/matlab/ref/reshape.html?searchHighlight=reshape&s_tid=doc_srcht ...
- 11 . Nginx核心原理讲解
应用场景优缺点 应用场景 // 1.静态请求 // 2.反向代理 // 3.负载均衡 // 4.资源缓存 // 5.安全防护 // 6.访问限制IP // 7.访问认证 /* 核心主要是以下三个应用: ...
- # vue 如何通过前端来导出excel表格
在做一些简单的demo时,偶尔会遇到导出excel表格.如果请后端帮忙的话 比较浪费时间,那么前端如何导出excel表格,下面就来记录一下之前使用到的案例 一.安装依赖 npm i file-save ...
- SpringBoot使用activiti自定义流程demo解析
环境搭建[这里直接讲解自定义流程] 集成 Activiti Modeler 下载源码 我这里选用的是 Activiti 5.23.0 版本的页面,下载 zip,解压 Activiti 5.23.0 源 ...
- Dubbo的负载均衡策略&容错策略
dubbo的负载均衡策略 RandomLoadBalance 随机调用负载均衡 默认方式该类实现了抽象的AbstractLoadBalance接口,重写了doSelect方法,看方法的细节就是首先遍历 ...
- CSS的背景
CSS的背景 1. 背景颜色background-color div { background-color: 颜色值; } 一般情况下元素背景颜色默认是transparent(透明). 2. 背景图片 ...
- 使用 volatile 关键字保证变量可见性和禁止指令重排序
volatile 概述 volatile 是 Java 提供的一种轻量级的同步机制.相比于传统的 synchronize,虽然 volatile 能实现的同步性要差一些,但开销更低,因为它不会引起频繁 ...