[NOIP补坑计划]NOIP2015 题解&做题心得
感觉从15年开始noip就变难了?(虽然自己都做出来了……)
场上预计得分:100+100+60~100+100+100+100=560~600(省一分数线365)
题解:
D1T1 神奇的幻方
水题送温暖~
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
int n,x,y,a[][];
int main(){
scanf("%d",&n);
x=,y=(n+)/;
for(int i=;i<=n*n;i++){
a[x][y]=i;
if(x==&&y==n)x++;
else if(x==)x=n,y++;
else if(y==n)x--,y=;
else if(a[x-][y+])x++;
else x--,y++;
}
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
printf("%d ",a[i][j]);
}
puts("");
}
return ;
}
D1T2 信息传递
题意就是求最小环,可以用tarjan也可以直接用并查集;
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
int n,ans=inf,tmp,a[],fa[],las[];
int ff(int u){
return u==fa[u]?u:fa[u]=ff(fa[u]);
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
fa[i]=las[i]=i;
}
for(int i=;i<=n;i++){
int fu=ff(i),fv=ff(a[i]);
if(fu==fv){
tmp=;
for(int v=a[i];v!=i;v=las[v])tmp++;
ans=min(ans,tmp);
}else fa[fu]=fv;
las[fu]=a[i];
}
printf("%d",ans+);
return ;
}
D1T3 斗地主
做了xfz那题就会这题了……场上的话不一定会写,所以期望得分60~100?
题解见这篇博客
D2T1 跳石头
水题送温暖~
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
int L,n,m,l,r,ans,d[];
bool chk(int k){
int ret=,nw=;
for(int i=;i<=n;i++){
if(d[i]-d[nw]<k)ret++;
else nw=i;
}
return ret<=m;
}
int main(){
scanf("%d%d%d",&L,&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&d[i]);
}
l=,r=L;
while(l<=r){
int mid=(l+r)/;
if(chk(mid))ans=mid,l=mid+;
else r=mid-;
}
printf("%d",ans);
return ;
}
D2T2 子串
好题!深刻体现了我计数dp能力蒻的事实……显然设$f[i][j][k]$表示在$A$中用到第$i$位,在$B$中用到第$j$位,已经分出了$k$个子串的方案数;
如果$A[i]=B[j]$,则可以选择当前位,那么有两种情况:
1.继承上一位的子串,k不变;
2.以$i$为开头新创一个子串,k++;
直接转移不太好搞,那么再设$g[i][j][k]$表示当前必须要新创子串的方案数,和$f$一起转移;
转移方程为$f[i][j][k]=f[i-1][j][k]+g[i][j][k],g[i][j][k]=g[i-1][j-1][k]+f[i-1][j-1][k-1]$
直接dp会爆空间,注意到转移的时候只用到了$i$和$i-1$,用滚动数组优化即可;
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
#define mod 1000000007
using namespace std;
typedef long long ll;
int n,m,K,t=,f[][][],g[][][];
char a[],b[];
int main(){
scanf("%d%d%d%s%s",&n,&m,&K,a+,b+);
f[][][]=;
for(int i=;i<=n;i++){
t^=;
f[t][][]=;
for(int j=;j<=m;j++){
for(int k=;k<=K;k++){
if(a[i]==b[j]){
g[t][j][k]=(g[t^][j-][k]+f[t^][j-][k-])%mod;
}else g[t][j][k]=;
f[t][j][k]=(f[t^][j][k]+g[t][j][k])%mod;
}
}
}
printf("%d",f[t][m][K]);
return ;
}
D2T3 运输计划
看上去挺难,思路还蛮清晰的?首先显然二分答案,记录下长度大于当前答案k的路径的数量,删掉的那条边肯定在这些路径的并上,所以求出这些路径的并后找到其中最长的那条边,判最长的那条路径减去这条边后能否小于等于k即可。
具体实现可以记录每个点的父边长度,倍增预处理每条路径,用树上差分求出路径的交,时间复杂度是$O((n+m)log\sum t_i)$,正好能过?我loj第一次被卡了一个点大概50ms,加了读入优化就过了……(洛咕依旧秒过)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
using namespace std;
typedef long long ll;
struct edge{
int v,w,next;
}a[];
int n,m,u,v,w,ans,maxn,l,r,num[],fr[],x[],y[],lca[],d[],tot=,head[],dis[],dep[],fa[][];
char buffer[],*hd,*tl;
inline char Getchar(){
if(hd==tl){
int len=fread(buffer,,,stdin);
hd=buffer,tl=hd+len;
if(hd==tl)
return EOF;
}
return *hd++;
}
inline int rd(){
register int x=,f=;
char c;
do{
c=Getchar();
if(c=='-')f=-;
}while(!isdigit(c));
do{
x=(x<<)+(x<<)+(c^);
c=Getchar();
}while(isdigit(c));
return x*f;
}
void add(int u,int v,int w){
a[++tot].v=v;
a[tot].w=w;
a[tot].next=head[u];
head[u]=tot;
}
void dfs(int u,int ff,int dpt,int ds){
dep[u]=dpt;
dis[u]=ds;
fa[u][]=ff;
for(int i=;i<=;i++){
fa[u][i]=fa[fa[u][i-]][i-];
}
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=ff){
fr[v]=a[tmp].w;
dfs(v,u,dpt+,ds+a[tmp].w);
}
}
}
int getlca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
int l=dep[u]-dep[v];
for(int i=;i>=;i--){
if((<<i)&l){
u=fa[u][i];
}
}
if(u==v)return u;
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i],v=fa[v][i];
}
}
return fa[u][];
}
void getn(int u,int fa){
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(v!=fa){
getn(v,u);
num[u]+=num[v];
}
}
}
bool chk(int k){
int cnt=,mx=;
for(int i=;i<=n;i++)num[i]=;
for(int i=;i<=m;i++){
if(d[i]>k){
cnt++;
num[x[i]]++;
num[y[i]]++;
num[lca[i]]-=;
}
}
getn(,);
for(int i=;i<=n;i++){
if(num[i]>=cnt)mx=max(mx,fr[i]);
}
return maxn-mx<=k;
}
int main(){
memset(head,-,sizeof(head));
//scanf("%d%d",&n,&m);
n=rd(),m=rd();
for(int i=;i<n;i++){
//scanf("%d%d%d",&u,&v,&w);
u=rd(),v=rd(),w=rd();
add(u,v,w);
add(v,u,w);
}
dfs(,,,);
for(int i=;i<=m;i++){
//scanf("%d%d",&x[i],&y[i]);
x[i]=rd(),y[i]=rd();
lca[i]=getlca(x[i],y[i]);
d[i]=dis[x[i]]+dis[y[i]]-dis[lca[i]]*;
maxn=max(maxn,d[i]);
}
l=,r=maxn;
while(l<=r){
int mid=(l+r)/;
if(chk(mid))ans=mid,r=mid-;
else l=mid+;
}
printf("%d",ans);
return ;
}
总结:
1.这次差不多花了四个半小时做完所有题,保持速度的同时要稳,遇到难题还是要仔细思考,分析题目性质,坚信正解并不会很难
2.计数DP(其实是所有DP)水平要加强
3.感觉1314年真的水的厉害……做15年的题明显感觉到了差别,大力切题爽爽
[NOIP补坑计划]NOIP2015 题解&做题心得的更多相关文章
- [NOIP补坑计划]NOIP2017 题解&做题心得
终于做完了…… 场上预计得分:?(省一分数线:295) 由于看过部分题解所以没有预计得分qwq 题解: D1T1 小凯的疑惑 题面 震惊!一道小学奥数题竟难倒无数高中考生! 欢迎大家以各种姿势*和谐* ...
- [NOIP补坑计划]NOIP2012 题解&做题心得
场上预计得分:100+90+70+100+100+3060=490520(省一分数线245) 题解: D1T1 Vigenère 密码 题面 水题送温暖~~ #include<iostream& ...
- [NOIP补坑计划]NOIP2016 题解&做题心得
感觉16年好难啊QAQ,两天的T2T3是不是都放反了啊…… 场上预计得分:100+80+100+100+65+100=545(省一分数线280) ps:loj没有部分分,部分分见洛咕 题解: D1T1 ...
- [NOIP补坑计划]NOIP2013 题解&做题心得
场上预计得分:100+100+100+100+100+60=560(省一分数线410) 五道傻逼题+一道大搜索题…… 题解: D1T1 转圈游戏 题面 水题送温暖~ #include<algor ...
- [NOIP补坑计划]NOIP2014 题解&做题心得
六道普及组题,没啥好说的 场上预计得分:100+100+100+100+100+100=600(省一分数线490) (AK是不可能AK的,这辈子不可能AK的) 题解: D1T1 生活大爆炸版石头剪刀布 ...
- [BJOI2016]水晶 做题心得
[BJOI2016]水晶 做题心得 这是一个写了我两小时的傻逼题.写这个题浪费了一堆时间后,我才意识到我码力又不行了.于是整理起了实现技巧,开始练码力. 思路 不难.首先把 \((x,y,z)\) 变 ...
- CF1416D 做题心得
CF1416D 做题心得 上次在某trick中提到了这个题,一开始觉得太毒瘤没有写,现在把它补上了. 感觉实现这个东西,比单纯收获一个trick,收获的东西多太多了. 主要思路 它的主要trick是& ...
- [JSOI2019]节日庆典 做题心得
[JSOI2019]节日庆典 做题心得 一个性质有趣的字符串题 这要是在考场上我肯定做不出来吧 一开始还以为要 SAM 什么的暴力搞,没想到只用到了 \(Z\) 函数 -- 也是我生疏了罢 (学了啥忘 ...
- 2018.我的NOIP补全计划
code: efzoi.tk @ shleodai noip2011 D1 选择客栈 这道题是一道大水题,冷静分析一会就会发现我们需要维护最后一个不合法点和前缀和. 维护最后一个不合法点只要边扫描边维 ...
随机推荐
- 在wamp中直接进入项目
这个问题困扰了我很久, 暂时我解决了一半. 进入localhost的页面如图一: 可以看到 我有两个projects,但是点击后会直接转跳到这样的页面 例如点击phyfitness_proj,如图二所 ...
- 洛谷P1914 小书童——密码
题目背景 某蒟蒻迷上了"小书童",有一天登陆时忘记密码了(他没绑定邮箱or手机),于是便把问题抛给了神犇你. 题目描述 蒟蒻虽然忘记密码,但他还记得密码是由一串字母组成.且密码是由 ...
- /etc/default/useradd文件内容及对应功能
1.GROUP=100 #依赖于/etc/login.defs的USE RGRUUPS_ENAB参数,如果为no,则在此处控制 2.HOME=/home #把用户的家路径健在/home中 3.INAC ...
- 运行级别(init)
一.运行级别(查看:cat /etc/inittab) 级别: 0:关机 1:服务器出问题(单用户状态) 2:无NFS的多用户模式 3:完整的多用户模式 4:无保留无使用 5:桌面模式 6:重新启动 ...
- fun(int **p)的使用
#include <iostream>using namespace std;void fun(int **p){ cout << p[0][0] << endl; ...
- Java基础学习总结(63)——Java集合总结
数据结构是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作.Java提供了几个能有效地组织和操作数据的数据结构,这些数据结构通常称为Java集合框架.在平常的学习开发中,灵 ...
- <url-pattern>/</url-pattern> 拦截请求
一.springmvc 前端控制器 <!-- springmvc的前端控制器 --> <servlet> <servlet-name>fw-sso-web</ ...
- java import跨包引用类理解
当前类要用其他类时,import具体包路径+.+具体的类 import引入的是被引用类的class文件,所以当我们build path第三方jar包时, 要用他们的类,要把jar包add to bui ...
- 逆向学习XXclient怎样仅仅执行一个实例
个人觉得学习分两种, 一种是当面请教和直接从书本网络中的资料学习. 其二就是看着令你惊叹的作品-顿悟. 什么?顿悟不了?那我们就一起来逆向学习吧!差点忘了,我并不打算提供Demo,这并不重要,难道你打 ...
- C#实现调用接口数据获取数据格式化XML、json转成Table的方法
废话不多说,直接上代码: json 格式化转DataTable: result为从接口得到的数据,格式化json的方法主要来自Newtonsoft.Json JObject joUnit = JObj ...