NOIP 2012 提高组第二试模拟赛 Solution
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP 2012 提高组第二试模拟赛 Solution相关的知识,希望对你有一定的参考价值。
第一题
题意
数据范围
Solution
三分求下凹函数最值
1 #include <cstdio> 2 #include <queue> 3 #include <iostream> 4 using namespace std; 5 inline void read(int &k) 6 { 7 k=0;int f=1;char c=getchar(); 8 while (c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); 9 while (c>=‘0‘&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar(); 10 k*=f; 11 } 12 const int maxn=1e5+100; 13 int n; 14 double a[maxn],b[maxn],c[maxn]; 15 double l,r,lmid,rmid,tmpl,tmpr,tmplm,tmprm; 16 inline double max(double a,double b) 17 { 18 if (a<b)return b; 19 return a; 20 } 21 inline double f(double x) 22 { 23 double ans=a[1]*x*x+b[1]*x+c[1]; 24 for (int i=2;i<=n;i++) 25 ans=max(a[i]*x*x+b[i]*x+c[i],ans); 26 return ans; 27 } 28 inline double abs(double a) 29 { 30 return a>0?a:-a; 31 } 32 int main() 33 { 34 freopen("curves.in","r",stdin); 35 freopen("curves.out","w",stdout); 36 read(n); 37 for (int i=1;i<=n;i++) 38 { 39 scanf("%lf%lf%lf",&a[i],&b[i],&c[i]); 40 } 41 l=0.0;r=1000.0; 42 do 43 { 44 lmid=l+(r-l)/3.0;rmid=l+(r-l)/3.0*2.0; 45 tmplm=f(lmid);tmprm=f(rmid); 46 if (f(lmid)>f(rmid))l=lmid;else r=rmid; 47 }while (abs(l-r)>1e-10); 48 printf("%.3lf\\n",f(lmid)); 49 }
第二题
数据范围
Solution
优先队列/堆模拟
1 #include <cstdio> 2 #include <queue> 3 #include <iostream> 4 using namespace std; 5 priority_queue<int> qmax; 6 priority_queue<int,vector<int>,greater<int> > qmin; 7 inline void read(int &k) 8 { 9 k=0;int f=1;char c=getchar(); 10 while (c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); 11 while (c>=‘0‘&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar(); 12 k*=f; 13 } 14 int l,n,tmp,cur=0,head=1;long long ans=0; 15 int main() 16 { 17 freopen("cate.in","r",stdin); 18 freopen("cate.out","w",stdout); 19 read(l);read(n); 20 for (int i=1;i<=n;i++) 21 { 22 read(tmp); 23 if (!tmp) 24 { 25 read(tmp); 26 if (tmp>=cur)qmin.push(tmp);else qmax.push(tmp); 27 } 28 else 29 { 30 if (head) 31 { 32 if (qmax.empty()&&qmin.empty())continue; 33 if (qmax.empty()) 34 { 35 ans+=qmin.top()-cur; 36 cur=qmin.top(); 37 qmin.pop(); 38 continue; 39 } 40 if (qmin.empty()) 41 { 42 ans+=cur-qmax.top(); 43 cur=qmax.top(); 44 qmax.pop(); 45 head=0; 46 continue; 47 } 48 if (cur-qmax.top()==qmin.top()-cur) 49 { 50 ans+=qmin.top()-cur; 51 cur=qmin.top(); 52 qmin.pop(); 53 } 54 else 55 { 56 if (qmin.top()-cur<cur-qmax.top())ans+=qmin.top()-cur,cur=qmin.top(),qmin.pop(); 57 else head=0,ans+=cur-qmax.top(),cur=qmax.top(),qmax.pop(); 58 } 59 } 60 else 61 { 62 if (qmax.empty()&&qmin.empty())continue; 63 if (qmax.empty()) 64 { 65 ans+=qmin.top()-cur; 66 cur=qmin.top(); 67 qmin.pop(); 68 head=1; 69 continue; 70 } 71 if (qmin.empty()) 72 { 73 ans+=cur-qmax.top(); 74 cur=qmax.top(); 75 qmax.pop(); 76 continue; 77 } 78 if (cur-qmax.top()==qmin.top()-cur) 79 { 80 ans+=cur-qmax.top(); 81 cur=qmax.top(); 82 qmax.pop(); 83 } 84 else 85 { 86 if (qmin.top()-cur>cur-qmax.top())ans+=cur-qmax.top(),cur=qmax.top(),qmax.pop(); 87 else head=1,ans+=qmin.top()-cur,cur=qmin.top(),qmin.pop(); 88 } 89 } 90 } 91 } 92 printf("%lld\\n",ans); 93 }
第三题
题意
数据范围
Solution
O(n^2)/60%:dfs(遍历整颗树)
1 #include <cstdio> 2 #include <queue> 3 #include <iostream> 4 #include <cstring> 5 #define ll long long 6 using namespace std; 7 inline void read(ll &k) 8 { 9 k=0;ll f=1;char c=getchar(); 10 while (c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar(); 11 while (c>=‘0‘&&c<=‘9‘)k=k*10+c-‘0‘,c=getchar(); 12 k*=f; 13 } 14 const int maxn=300100*2; 15 bool v[maxn]; 16 ll n,x,y,z,ans,la,tot,last[maxn],next[maxn],value[maxn],to[maxn],col[maxn]; 17 void dfs(int now,ll sum,int dep,int la) 18 { 19 v[now]=1; 20 for (int cur=last[now];cur;cur=next[cur]) 21 if ((col[cur]!=la)&&(!v[to[cur]])) 22 dfs(to[cur],sum+value[to[cur]],dep+1,col[cur]); 23 if (dep) 24 ans+=sum; 25 } 26 int main() 27 { 28 freopen("gorgeous.in","r",stdin); 29 freopen("gorgeous.out","w",stdout); 30 read(n); 31 for (int i=1;i<=n;i++) 32 read(value[i]); 33 for (int i=1;i<n;i++) 34 { 35 read(x);read(y);read(z); 36 next[++tot]=last[x]; 37 to[tot]=y; 38 col[tot]=z; 39 last[x]=tot; 40 next[++tot]=last[y]; 41 to[tot]=x; 42 col[tot]=z; 43 last[y]=tot; 44 } 45 for (int i=1;i<=n;i++) 46 { 47 memset(v,0,sizeof(v)); 48 dfs(i,value[i],0,0); 49 } 50 printf("%lld\\n",ans/2); 51 }
以上是关于NOIP 2012 提高组第二试模拟赛 Solution的主要内容,如果未能解决你的问题,请参考以下文章
数学方法模拟(洛谷1017 进制转换NOIp2000提高组第一题)
1402Vigenère密码(Noip2012提高组第1题)
唯一分解定理的应用: NOIP2009 提高组第二题Hankson [唯一分解定理|暴力]