10.11考试总结

来源:互联网 发布:opencv3编程入门 微盘 编辑:程序博客网 时间:2024/06/07 14:17

1.造盒子(100/100)

      题目大意:在一个网格中有两种木板,一种沿边,一种沿对角线,问框住k面积最少需要多少木板(可多余);

           感想:推了一个半小时总算推出来了,找规律,说明一下框住5最少需要7块木板,然后就简单了;

# include <iostream># include <cstdio># include <cstring># include <algorithm># include <queue># include <cmath>using namespace std;typedef long long ll;int Read(){int i=0,f=1;char c=getchar();while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}return i*f;}const double eps=1e-5;int t,n;int main(){t=Read();while(t--){    n=Read();    int l=1,r=1;    while(2*l*r<n)    {    if(l==r) r++;    else l++;    }    if((2*l*r-l-0.5)-n>0) printf("%d\n",(l+r)*2-1);    else printf("%d\n",(l+r)*2);  }}
2.分玩具(5/100)

      题目大意:2人分玩具,每个人轮流拿任意数量的玩具,每个玩具都有好玩值,每次得到的好玩值是拿到玩具中最小的,问先手的人最多比后手多多少好玩值;

           感想:考试时没读懂,随便贪心了一下,感觉很有道理的样子,结果wa成狗;正解:先排序,然后dp[i]表示剩下i个的最优解,o(n*n),然后发现其实是一个最小前缀值,所以维护一下o(n);

# include <iostream># include <cstdio># include <cstring># include <algorithm># include <queue># include <cmath>using namespace std;typedef long long ll;int Read(){int i=0,f=1;char c=getchar();while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}return i*f;}ll n,a[1000005],b[1000005];int main(){    n=Read();    for(int i=1;i<=n;++i) a[i]=Read();    sort(a+1,a+n+1);    ll ans=-1;    for(int i=1;i<=n;++i)    {    ans=max(a[i]-b[i-1],ans);    b[i]=ans;    }    printf("%lld\n",ans);}
3.problem(15/100)

    题目大意:给一个序列每次选一个大于k的数,在其傍边两个数中选一个+1,自己-1,经过m次操作后问最长的子序列(要求子序列中每个数不小于k)

       感想:不难发现每一段平均值大于n*k,那这一段就可行,所以需要找出平均值中大于k*n最长子序列,然后n*n树状数组跑了个暴力,拿了15分,很稳,我白痴认为可以二分长度,其实不难发现这个并不满足二分性,于是挂了。正解,先将每个数减k,求哪段最长且平均值大于k,我们先求出a数组的单调不增序列,用栈维护,然后从后扫一遍,找到刚好满足sum[i]-sum[k]>=0的点k,输出答案即可。

# include <iostream># include <cstdio># include <cstring># include <algorithm># include <queue># include <cmath>using namespace std;typedef long long ll;ll Read(){ll i=0,f=1;char c=getchar();while(c>'9'||c<'0') {if(c=='-') f=-1; c=getchar();}while(c>='0'&&c<='9') {i=i*10+(c-'0'); c=getchar();}return i*f;}ll a[1000005],sta[1000005],n,m,k,sum[1000005];int main(){   n=Read(),m=Read();for(int i=1;i<=n;++i) a[i]=Read();while(m--){    k=Read();    ll top=0;    for(int i=1;i<=n;++i)     {    sum[i]=sum[i-1]-k+a[i];    if(sum[sta[top]]>=sum[i]) sta[++top]=i;    }    ll ans=-1;    for(int i=n;i;--i)    {    while(sum[sta[top]]<=sum[i]&&top>=0) --top;    ans=max(ans,i-sta[top+1]);    }    cout<<ans<<" ";}}
    总结:学长出的题主要考思维,所以一定要仔细想,想最后一题从后往前扫就是需要思考的点,所以思维很重要;



原创粉丝点击