NOIP 2015 题解
来源:互联网 发布:像素人物制作软件 编辑:程序博客网 时间:2024/05/19 04:26
终于搞完了!!!!!
dalao们都说水,但蒟蒻表示挺难的;
有件事很开心;
其中四道题是自己独立AC的;
一道想到正解(Day 2 T3),但不会卡常;
至于还有一道……一点思路也没有(Day 2 T2);
Day 1
T1:
题目:
https://www.luogu.org/problem/show?pid=2615
模拟,日常签到题,注意坐标具有传递性;
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int ma[2001][2001],n,tot=1;void solve(){ scanf("%d",&n); ma[1][n/2+1]=tot; int x=1,y=n/2+1; while(tot<n*n) { tot++; if(x==1 && y!=n) x=n,y++; else if(x!=1 && y==n) y=1,x--; else if(x==1 && y==n) x++; else if(x!=1 && y!=n) { if(!ma[x-1][y+1]) x--,y++; else x++; } ma[x][y]=tot; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) cout<<ma[i][j]<<" "; cout<<endl; }}int main(){ solve(); return 0;}
T2:
题目:
https://www.luogu.org/problem/show?pid=2661
tarjan或dfs;
比较裸的求最小环;
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;stack<int>s;const int MAXN=200001;int dfn[MAXN],low[MAXN],fst[MAXN],nxt[MAXN],scc[MAXN];int n,tot,tim,cnt,f,ans=324252;struct hh{ int from,to;}map[MAXN];void build(int f,int t){ tot++; map[tot]=(hh){f,t}; nxt[tot]=fst[f]; fst[f]=tot; return;}void tarjan(int x){ low[x]=dfn[x]=++tim; s.push(x); for(int i=fst[x];i!=-1;i=nxt[i]) { int v=map[i].to; if(!dfn[v]) { tarjan(v); low[x]=min(low[x],low[v]); } else if(!scc[v]) low[x]=min(low[x],dfn[v]); } if(dfn[x]==low[x]) { cnt++; int num=0; while(true) { int u=s.top(); s.pop(); num++,scc[x]=cnt; if(u==x) { if(num>1) ans=min(num,ans); break; } } } return;}void solve(){ memset(fst,-1,sizeof(fst)); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&f); build(i,f); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); cout<<ans; return;}int main(){ solve(); return 0;}
T3:
题目:
https://www.luogu.org/problem/show?pid=2668
注意答案的更新;
挺简单的一道题,但是细节处理较多;
题解:http://blog.csdn.net/qq_36312502/article/details/77970178;
爆搜;
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int t,n,cnt[10001],ans,num;void init(){ memset(cnt,0,sizeof(cnt)); ans=n; return;}int cnt1,cnt2,cnt3,cnt4,cnt5;void dfs(int x){ cnt1=cnt2=cnt3=cnt4=cnt5=0; for(int i=1;i<=14;i++) { if(cnt[i]==1) cnt1++; else if(cnt[i]==2) cnt2++; } for(int i=1;i<=14;i++)//三带一 三带二 { if(cnt[i]==3) { cnt3++; if(cnt1>=1) cnt1--; else if(cnt2>=1) cnt2--; } } for(int i=1;i<=14;i++) //四带二 { if(cnt[i]==4) { cnt4++; if(cnt1>=2) cnt1-=2; else if(cnt2>=2) cnt2-=2; else if(cnt2>=1) cnt2--;//四带一个对子也可以; } } ans=min(ans,x+cnt1+cnt2+cnt3+cnt4); for(int i=1;i<=8;i++) //单顺子 { int j; for(j=i;j<=12;j++) { if(cnt[j]<1) break; cnt[j]--; if(j-i>=4) dfs(x+1); } for(int k=i;k<=j-1;k++) cnt[k]++; } for(int i=1;i<=10;i++) // 双顺子 { int j; for(j=i;j<=12;j++) { if(cnt[j]<2) break; cnt[j]-=2; if(j-i>=2) dfs(x+1); } for(int k=i;k<=j-1;k++) cnt[k]+=2; } for(int i=1;i<=11;i++) // 三顺子 { int j; for(j=i;j<=12;j++) { if(cnt[j]<3) break; cnt[j]-=3; if(j-i>=1) dfs(x+1); } for(int k=i;k<=j-1;k++) cnt[k]+=3; } return;}void solve(){ init(); int x,y; for(int i=1;i<=n;i++) { scanf("%d%d",&x,&y); if(x==0) cnt[14]++; else if(x==1) cnt[12]++; else if(x==2) cnt[13]++; else cnt[x-2]++; } dfs(0); cout<<ans<<endl;}int main(){ scanf("%d%d",&t,&n); int hh=t; while(hh--) solve(); return 0;}
Day 2
T1:
题目:
https://www.luogu.org/problem/show?pid=2678
二分;
题解:
http://blog.csdn.net/qq_36312502/article/details/77869900
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;int r,l=1,L,n,m,ans,last;int a[100001];bool check(int x){ int ans=0,last=0; for(int i=1;i<=n+1;i++) { if(a[i]-last<x) ans++; else last=a[i]; } if(ans>m) return 1; else return 0;}void solve(){ cin>>L>>n>>m; for(int i=1;i<=n;i++) scanf("%d",&a[i]); r=a[n+1]=L; while(r-l>1) { int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid; } if(!check(r)) l=r; cout<<l;}int main(){ solve(); return 0;}
T2:
题目:
https://www.luogu.org/problem/show?pid=2679
DP,难;
题解:
http://blog.csdn.net/qq_36312502/article/details/78127290
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int mod=1000000007;int dp[3][301][301][3],cnt,now,pre=1,n,m,t;char s1[1021],s2[1021];void solve(){ cin>>n>>m>>t; scanf("%s%s",s1+1,s2+1); for(int i=1;i<=n;i++) { swap(now,pre); dp[now][1][1][0]=cnt; if(s1[i]==s2[1]) dp[now][1][1][1]=1,cnt++; for(int j=2;j<=m;j++) { for(int k=1;k<=t;k++) { if(s1[i]==s2[j]) dp[now][j][k][1]=((dp[pre][j-1][k-1][0]+dp[pre][j-1][k-1][1])%mod+dp[pre][j-1][k][1])%mod; dp[now][j][k][0]=(dp[pre][j][k][0]+dp[pre][j][k][1])%mod; } } for(int j=1;j<=m;j++) for(int k=1;k<=t;k++) dp[pre][j][k][1]=dp[pre][j][k][0]=0; } cout<<(dp[now][m][t][1]+dp[now][m][t][0])%mod; return;}int main(){ solve(); return 0;}
T3:
题目:
https://www.luogu.org/problem/show?pid=2680
lca+树上差分+二分;
题解:
http://blog.csdn.net/qq_36312502/article/details/78121945
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int MAXN=600008;int fst[MAXN],nxt[MAXN],num[MAXN],tmp[MAXN],dis[MAXN];int deep[MAXN],top[MAXN],sz[MAXN],fa[MAXN],son[MAXN],dfn[MAXN];int tot,n,m,l=-1,r,totp;struct hh {int from,to,cost;}ss[MAXN];struct edge {int from,to,lca,dis;}ma[MAXN];void build(int f,int t,int c){ tot++; ss[tot]=(hh){f,t,c}; nxt[tot]=fst[f]; fst[f]=tot; return;}void dfs1(int x,int f,int c){ dfn[++totp]=x; fa[x]=f,deep[x]=deep[f]+1,sz[x]=1,dis[x]=c; for(int i=fst[x];i;i=nxt[i]) { int v=ss[i].to; if(v==f) continue; num[v]=ss[i].cost; dfs1(v,x,c+ss[i].cost),sz[x]+=sz[v]; if(!son[x] || sz[son[x]]<sz[v]) son[x]=v; } return;}void dfs2(int x,int st){ top[x]=st; if(!son[x]) return; dfs2(son[x],st); for(int i=fst[x];i;i=nxt[i]) { int v=ss[i].to; if(v==fa[x] || v==son[x]) continue; dfs2(v,v); } return;}int lca(int x,int y){ int fx=top[x],fy=top[y]; while(fx!=fy) { if(deep[fx]<deep[fy]) swap(fx,fy),swap(x,y); x=fa[fx],fx=top[x]; } return deep[x]<deep[y]?x:y;}bool check(int ans){ int lim=-1,cnt=0; memset(tmp,0,sizeof(tmp)); for(int i=1;i<=m;i++) { if(ma[i].dis>ans) { tmp[ma[i].from]++,tmp[ma[i].to]++; tmp[ma[i].lca]-=2; lim=max(lim,ma[i].dis-ans); cnt++; } } if(!cnt) return true; for(int i=n;i>=1;i--) tmp[fa[dfn[i]]]+=tmp[dfn[i]]; for(int i=2;i<=n;i++) if(num[i]>=lim && tmp[i]==cnt) return true; return false;}void solve(){ int x,y,z; scanf("%d%d",&n,&m); for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); build(x,y,z),build(y,x,z); r+=z; } dfs1(1,0,0),dfs2(1,1); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); ma[i]=(edge){x,y,lca(x,y),dis[x]+dis[y]-2*dis[lca(x,y)]}; } while(r-l>1) { int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid; } cout<<r; return;}int main(){ solve(); return 0;}
- NOIP 2015 简要题解
- NOIP 2015 题解
- NOIP 2015提高组 题解+分析
- NOIP 2015模拟赛[八中题]题解&总结
- NOIP 2015模拟赛 题解&总结
- PPFish-NOIP模拟题2015题解
- NOIP 2010 题解
- NOIP 2012 题解
- NOIP模拟21题解
- NOIP模拟题题解
- NOIP-2016-普及-题解
- NOIP-2009-提高-题解
- Noip 2013 day1 题解
- NOIP 2004 题解
- NOIP 2010 题解
- NOIP 2009 题解+代码
- NOIP 2010 题解+代码
- NOIP 2011 题解+代码
- Linux下的tar压缩解压缩命令详解
- 步进电机麦轮小车程序编写
- 数据结构实验之栈与队列八:栈的基本操作
- vue mint-ui 使用手册
- 学生选课系统库表设计
- NOIP 2015 题解
- MySQL巡检怎么做
- InnoDB Buffer Pool巧配置全解
- MySQL 5.7怎么爬出临时表空间的坑
- 老司机带你体验SYS库多种新玩法
- MySQL 8.0.2复制新特性抢鲜看
- InnoDB MVCC何时创建read view
- 网络赚钱方法之游戏试玩赚钱
- java实现打印功能