Day1

T1 小凯的疑惑

题目传送门

考场上打表搞了一个很奇怪的结论,化简后就是a∗b−a−ba*b-a-ba∗b−a−b。具体证明现在还是不大会。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL a,b;
int main(){scanf("%lld%lld",&a,&b);if (a>b) swap(a,b);if (a==1){printf("0\n");return 0;}if (a==2){printf("%lld\n",b-2);fclose(stdin);fclose(stdout);return 0;}LL ans=(4+(a-3)*2+4)*(a-2)/2+1;ans+=(b-a-1)*(a-1);printf("%lld\n",ans);return 0;
}

T2 时间复杂度

题目传送门

一般用一个栈模拟,细节比较多。没什么好说的。

考场上写的代码只会统计第一个循环。。。然而还是有80。

当时太紧张就写得很丑。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100
using namespace std;
struct Orz{char c;bool f;
}stack[MAXN+5];
int top,t,l,cmp,a[MAXN+5],ma;
int f;
char s[MAXN+5],sc[MAXN+5],sx[MAXN+5],sy[MAXN+5];
int main(){scanf("%d",&t);while (t--){memset(a,0,sizeof(a));f=0; top=0; cmp=0; ma=0;scanf("%d%s",&l,s);if (s[2]=='n') f=1;for (int i=0;s[i];i++)if (s[i]>='0'&&s[i]<='9')cmp=cmp*10+s[i]-48;int num=0;bool flag=false,fa=false,fl=false; if (l&1) flag=true;for (int i=1;i<=l;i++){int ff=0; char ss[2];scanf("%s",ss);ff=ss[0];if (ff=='F'){int c,x=0,y=0;scanf("%s%s%s",sc,sx,sy);c=sc[0];for (int j=0;sx[j];j++)if (sx[j]>='0'&&sx[j]<='9')x=x*10+sx[j]-48;for (int j=0;sy[j];j++)if (sy[j]>='0'&&sy[j]<='9')y=y*10+sy[j]-48;if (sx[0]=='n') x='n';if (sy[0]=='n') y='n';if (flag) continue;if (a[c-'a']){ flag=true; continue; }if (x=='n'&&y!='n') fl=true;if (x!='n'&&y!='n'&&x>y) fl=true;if (x!='n'&&y=='n') num++;if (x!='n'&&y=='n'&&(!fl)) fa=true,ma=max(ma,num);a[c-'a']++; Orz p; p.c=c;if (x!='n'&&y=='n') p.f=true;else p.f=false;stack[++top]=p;}else{if (!top) { flag=true; continue; }if (stack[top].f) num--;a[stack[top--].c-'a']--;if (!top) fl=false;}}if (top) flag=true;if (flag){printf("ERR\n");continue;}if ((fa&&(f==0))||(ma!=cmp&&(f==1))){printf("No\n");continue;}printf("Yes\n");}return 0;
}

T3 逛公园

题目传送门

最短路+记忆化搜索

考场上用最短路优化一下就有60了。。。

先刷一遍反图最短路求出每个点到nnn的最短路dis[i]dis[i]dis[i]。

记f[i][j]f[i][j]f[i][j]表示到第iii个点,超出最短路的路程≤j\leq j≤j的方案数。搜索的时候对每条边的转移f[i][j]=∑f[v][j−d]f[i][j]=\sum f[v][j-d]f[i][j]=∑f[v][j−d]。其中d=dis[v]−dis[i]+wd=dis[v]-dis[i]+wd=dis[v]−dis[i]+w。判0环的话就记录一下当前状态有没有在访问路径上即可。

代码:

#include<queue>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
#define F inline
using namespace std;
struct P{ int x,d; };
struct edge{ int nxt,to,d; }ed[N<<2];
int n,m,k,p,K,d[N],h1[N],h2[N],f[N][55];
priority_queue<P> q; bool v[N][55];
F char readc(){static char buf[100000],*l=buf,*r=buf;if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);return l==r?EOF:*l++;
}
F int _read(){int x=0; char ch=readc();while (!isdigit(ch)) ch=readc();while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();return x;
}
#define add(h,x,y,z) ed[++k]=(edge){h[x],y,z},h[x]=k
F bool operator <(P a,P b){ return a.d>b.d; }
F void Dij(){while (!q.empty()) q.pop();for (q.push((P){n,d[n]=0});!q.empty();q.pop()){int x; if (q.top().d>d[x=q.top().x]) continue;for (int i=h2[x],v;i;i=ed[i].nxt)if (d[v=ed[i].to]>d[x]+ed[i].d)d[v]=d[x]+ed[i].d,q.push((P){v,d[v]});}
}
int dfs(int x,int k){if (v[x][k]) return -1; if (f[x][k]) return f[x][k];v[x][k]=true,f[x][k]+=(x==n);for (int i=h1[x],v,w;i;i=ed[i].nxt)if ((w=d[v=ed[i].to]-d[x]+ed[i].d)<=k)if (dfs(v,k-w)==-1) return -1;else (f[x][k]+=f[v][k-w])%=p;return v[x][k]=false,f[x][k];
}
int main(){for (int t=_read();t;t--){n=_read(),m=_read(),K=_read(),p=_read(),k=0;for (int i=1;i<=n;i++) h1[i]=h2[i]=0,d[i]=1e9;for (int i=1;i<=n;i++)for (int j=0;j<=K;j++) f[i][j]=v[i][j]=0;for (int i=1,x,y,z;i<=m;i++){x=_read(),y=_read(),z=_read();add(h1,x,y,z),add(h2,y,x,z);}Dij(),printf("%d\n",dfs(1,K));}return 0;
}

Day2

T1 奶酪

题目传送门

并查集/BFS都可以。本来会爆long long的但是出题人没有卡。判断的时候移个项就好了

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1000
#define sqr(x) ((x)*(x))
using namespace std;
typedef long long LL;
struct edge{int next,to;
}ed[MAXN*MAXN*6+5];
struct node{LL x,y,z;
}a[MAXN*2+5];
int t,n,k;
LL m,r;
int h[MAXN*2+5],que[MAXN*2+5];
bool f[MAXN*2+5];
void addedge(int x,int y){ed[++k].next=h[x]; ed[k].to=y; h[x]=k;
}
LL calc(node a,node b){return sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z);
}
bool bfs(int s,int t){memset(f,false,sizeof(f));int r=0,w=1; que[1]=s; f[s]=true;while (r<w){int x=que[++r];for (int i=h[x];i;i=ed[i].next)if (!f[ed[i].to]){que[++w]=ed[i].to;f[ed[i].to]=true;}}return f[t];
}
int main(){scanf("%d",&t);while (t--){memset(h,0,sizeof(h)); k=0;scanf("%d%lld%lld",&n,&m,&r);for (int i=1;i<=n;i++){scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);if (a[i].z<=r) addedge(MAXN+2,i);if (a[i].z+r>=m) addedge(i,MAXN+1); }for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++)if (calc(a[i],a[j])<=sqr(r*2))addedge(i,j),addedge(j,i);if (bfs(MAXN+2,MAXN+1)) printf("Yes\n");else printf("No\n");}return 0;
}

T2 宝藏

题目传送门

状压DP

为什么我会觉得prim是对的!为什么我70分的暴力都不打!果然我好菜

我是不会告诉你我不知道怎么枚子集的

n=12就是状压的范围。据说标算O(4n)​O(4^n)​O(4n)​我不会啊,优化过的O(n3n)​O(n3^n)​O(n3n)​我也不会啊,我只会O(n23n)​O(n^23^n)​O(n23n)​啊不管了能过就行!

Orz写模拟退火的

f[i][j][s]f[i][j][s]f[i][j][s]表示以iii为根的子树中,iii的深度的为jjj,子树中的节点集合为sss的最小代价。那么有f[i][j][s]=min{f[k][j+1][ss]+f[i][j][s−ss]+a[i][k]}f[i][j][s]=min\{f[k][j+1][ss]+f[i][j][s-ss]+a[i][k]\}f[i][j][s]=min{f[k][j+1][ss]+f[i][j][s−ss]+a[i][k]},其中ssssss是sss的子集,kkk为ssssss内的一个点。时间复杂度为O(n33n)O(n^33^n)O(n33n)。

把转移方程中与sss无关的提取出来,预处理g[i][j][s]=min{f[k][j+1][s]+a[i][k]}g[i][j][s]=min\{f[k][j+1][s]+a[i][k]\}g[i][j][s]=min{f[k][j+1][s]+a[i][k]},这样就是O(n23n)O(n^23^n)O(n23n)的了。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 15
#define M (1<<12)+1
using namespace std;
int n,m,ans=1e9,a[N][N],f[N][N][M],g[N][N][M];
int main(){scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)for (int j=1;j<=n;j++){a[i][j]=1e9;for (int s=1;s<1<<n;s++)if (s!=1<<i-1) f[i][j][s]=g[i][j][s]=1e9;}for (int i=1,x,y,z;i<=m;i++)scanf("%d%d%d",&x,&y,&z),a[x][y]=a[y][x]=min(a[x][y],z);for (int j=n-1;j;j--)for (int i=1;i<=n;i++)for (int s=1;s<1<<n;s++){for (int k=1;k<=n;k++)if (((1<<k-1)&s)&&a[i][k]!=1e9)g[i][j][s]=min(g[i][j][s],f[k][j+1][s]+a[i][k]*j);for (int ss=s&s-1;ss;ss=ss-1&s)f[i][j][s]=min(f[i][j][s],f[i][j][s^ss]+g[i][j][ss]);}for (int i=1;i<=n;i++) ans=min(ans,f[i][1][(1<<n)-1]);return printf("%d\n",ans),0;
}

T3 列队

题目传送门

线段树动态开点

去年不会动态开点啊。。。
建n+1棵树,前n棵维护当前这行(除了最后一列),第n+1棵维护最后一列。每次操作的时候分操作的列是不是最后一列讨论一下就好了。
细节有点多,调了好久最后还是借鉴了一下题解。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 300005
#define F inline
using namespace std;
typedef long long LL;
struct tree{ int ls,rs,sz; LL x; }t[N<<6];
int n,m,q,mx,nd,rt[N],p[N]; LL ans,tmp;
F char readc(){static char buf[100000],*l=buf,*r=buf;if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);return l==r?EOF:*l++;
}
F int _read(){int x=0; char ch=readc();while (!isdigit(ch)) ch=readc();while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();return x;
}
F void writec(LL x){ if (x>9) writec(x/10); putchar(x%10+48); }
#define pd(l,r,f) (f==n+1?max(min(r,n)-l+1,0):max(min(r+1,m)-l,0))
F void nsrt(int &x,int l,int r,int p,LL w,int f){if (!x) t[x=++nd].sz=pd(l,r,f); int mid=l+r>>1;t[x].sz++; if (l==r) return void(t[x].x=w);if (p<=mid) nsrt(t[x].ls,l,mid,p,w,f);else nsrt(t[x].rs,mid+1,r,p,w,f);
}
F LL srch(int &x,int l,int r,int w,int f){if (!x) t[x=++nd].sz=pd(l,r,f); int mid=l+r>>1,p; t[x].sz--;if (l==r) return t[x].x?t[x].x:t[x].x=(f<=n?1ll*(f-1)*m+l:1ll*l*m);if (w<=(p=t[x].ls?t[t[x].ls].sz:mid-l+1))return srch(t[x].ls,l,mid,w,f);else return srch(t[x].rs,mid+1,r,w-p,f);
}
F LL calc(int x,int y){LL ans,tmp=srch(rt[n+1],1,mx,x,n+1);ans=y!=m?srch(rt[x],1,mx,y,x):tmp;if (y!=m) nsrt(rt[x],1,mx,++p[x],tmp,x);return nsrt(rt[n+1],1,mx,++p[n+1],ans,n+1),ans;
}
int main(){n=_read(),m=_read(),q=_read(),mx=max(n,m)+q;for (int i=1;i<=n+1;i++) p[i]=(i==n+1?n:m-1);for (int x,y;q;q--) x=_read(),y=_read(),writec(calc(x,y)),puts("");return 0;
}

NOIP2018要苟住啊

UPD 2018.11.11 假的,要退役了

NOIp2017 题解相关推荐

  1. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  2. NOIP2017提高组初赛 个人理解+题解

    NOIP2017复赛总结+题解 今年初赛好难啊 单选 第一题就懵逼 谁知道Pascal什么时候用不了啊 听说是2019年 选项里没有啊 那就2020年吧,果然错,答案是2022 第二题还是很正常,负数 ...

  3. noip2017爆炸记——题解总结反省(普及组+提高组)

    相关链接: noip2018总结 noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高 ...

  4. 牛客题库 题解 | #[NOIP2017]图书管理员#

    链接:#[NOIP2017]图书管理员# 题目牛客网是互联网求职神器,C++.Java.前端.产品.运营技能学习/备考/求职题库,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨 ...

  5. 洛谷 P3959 [NOIP2017]宝藏 题解

    通向地底的传送门 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的$ m$ 条道路和它们的长度. 小明决 ...

  6. P3955 [NOIP2017 普及组] 图书管理员C++题解

    洛谷来源:P3955 [NOIP2017 普及组] 图书管理员 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/sol ...

  7. [NOIP2017 普及组]跳房子 【题解】

    题目背景 NOIP2017 普及组 T4 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n n ...

  8. 【NOIP2017 提高组正式赛】列队 题解

    题目大意 有一个 \(n\times m\) 的方阵,每次有 \((x,y)\) 离开,离开后有两个命令 向左看齐.这时第一列保持不动,所有学生向左填补空缺.这条指令之后,空位在第 \(x\) 行第 ...

  9. NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解

    肝了两题... T1一眼题,分解质因数,找出2的个数和5的个数取min输出 #include<iostream> #include<cstring> #include<c ...

  10. NOIP2017(不算是题解)

    老年退役选手来过时口胡一波 小凯的疑惑 考场上的普遍做法就是打表吧,规律还是很好找的 很容易看出答案是a*b-a-b 时间复杂度 比16年的D1T2不知道良心多少... 模拟就行了,但还是需要一定的比 ...

最新文章

  1. ubuntu sudoers配置错误
  2. iOS:极光推送控制器跳转
  3. javascript函数,值得参考!
  4. jvm lock低性能分析
  5. 爬虫数据传入mysql_nodejs爬虫数据存入mysql
  6. Opera Unite如何架设自己的网站
  7. Debian 7 Wheezy 安装 VirtualBox
  8. STM32 FreeRTOS系列教程(一)FreeRTOS简介
  9. 点云数据处理(分类、分割、检测)PointNet
  10. linux 手动修复分区表,分区表修复
  11. 微信8.0表情没有特效怎么回事
  12. 接口限流算法(关于临界点处理)
  13. js前端生成excel文件(表格)并下载
  14. 企业级和个人苹果帐号AppleId申请
  15. 暴雪即将公布《暗黑破坏神3》新职业
  16. html5indexeddb排序,html5的indexedDB数据库操作实例
  17. MATLAB2018B下用Faster-RCNN做目标检测的训练和测试步骤
  18. 学法减分助手PRO小程序源码
  19. Unity打造科技风智慧城市夜景教程
  20. Python — “输入直角边求斜边”

热门文章

  1. Flash Player离线安装包下载指南
  2. 【AD18】原理图生成PDF
  3. 地图上导出坐标html文件,如何将标签的坐标、海拔等属性导出到TXT文本中
  4. 测试用例设计之正交表设计
  5. 3dmax模型在web端
  6. C语言实现sin函数的程序设计
  7. hp1008win7驱动问题
  8. VMware Workstation 16.2 Pro for Windows SLIC 2.6 Unlocker
  9. Java 之父 James Gosling 最新访谈:JIT 很好,但不适合所有语言
  10. 微星主板黑苹果_记一次黑苹果PC装机全过程