總結——關於2017 10 11測試的分析總結

来源:互联网 发布:韩顺平java水平如何 编辑:程序博客网 时间:2024/06/05 05:13

NOIP 2017 模拟



2017 10 11





T1 :


题目 :




大意:用最少的长度为1和根号2的边围出一个多边形使面积大于等于给定值。


——正解思路:

手动计算找规律。

显然要用最少的边围出最大的面积。

当边为偶数时,我们需要找一个最接近正方形的矩形,此时边都在对角线上。

当边为奇数时,我们在偶数边的基础上,将最长边拆开,增加一条边使面积增大。

根据边数预处理加二分。

——我的乱搞:

疑似发现了什么数学规律,然后英勇牺牲。


tips:

好好学习数学。。。。



正解 :


#include<cstdio>int main(){int n,t,l,r;scanf("%d",&t);while(t--){scanf("%d",&n);l=r=1;while(2*l*r<n) l==r ? ++r : l++;printf("%d\n",2*l*r-n<1e-5 ? l+r<<1 : 2*l*r-l-0.5-n>0 ? (l+r)*2-1 : l+r<<1);}return 0;}





T2 :


题目:





——正解思路:

这实际上是一个前缀最小值,所以拿数组维护一下就好了。

——我的乱搞:

诶WC,这竟然还是数学题??!


tips:

深感数学的重要性。


dp学得好的人数学都不会太差。 ——zgs





正解:

#include<cstdio>#include<algorithm>int n,__max,a[1000001];inline int read(){int i=0;char c=getchar();while(c<'0'||c>'9') c=getchar();while(c>='0'&&c<='9') i=(i<<3)+(i<<1)+c-48,c=getchar();return i;}int main(){n=read();for(int i=1;i<=n;++i) a[i]=read();std::sort(a+1,a+1+n);__max=a[1];for(int i=1;i<n;++i) if(a[i+1]>__max<<1) __max=a[i+1]-__max;printf("%d\n",__max);return 0;}






T3 :


题目:





——正解思路:

首先求出关于ai单调不增的栈s, 然后从右向左扫,由于求的是最大的r - 1,所以现在r (当前在 i )是逐渐减小。

那么 l (假设为 j ) 也要逐渐减小才对答案有贡献,所以就存在一个 k ( k > j ) 满足 si - sk >= 0 ,对答案也是没贡献的。

所以我们找到在栈里一个最小的 j 满足 si - sj >= 0 即可。

——我的乱搞

以为又是什么数学题,搞了一套很奇奇怪怪的方法,然后。。。。。。


tips :

把上面两条tips中和一下。。





正解:

#include<iostream>#include<algorithm>#include<cstdio>using namespace std;int n,m,k,ans,index,a[1000001],s[1000001];long long b[1000001];int main(){ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cin>>n>>m;for(int i=1;i<=n;++i) cin>>a[i];while(m--){cin>>k;index=1;s[index]=0;for(int i=1;i<=n;++i){b[i]=a[i]-k+b[i-1];if(b[s[index]]>b[i]) s[++index]=i;}ans=0;for(int i=n;i;--i){while(b[s[index]]<=b[i]&&index>=0) --index;ans=max(ans,i-s[index+1]);}cout<<ans<<" ";}return 0;}


原创粉丝点击