2019.9.21 csp-s模拟测试49 反思总结

没赶上昨天的考试,不过我这种人考不考都没有多少提升吧。

挺服气的一场考试,有生以来参加的最让人想笑的考试。

 

T1:养花

取模,区间询问最大值,有点套路化的预处理答案…难点也在预处理上。容易想到分块然后依次处理每个块的答案。

然后考虑每个块内怎么处理每个k。发现对于一个模数k,最大值一定是每个k的倍数的前驱,即比k小的最大值、比k*2小的最大值,比k*3小的最大值…这些数取max,然后%k。

那么在每个块内先扫一遍存下所有值,然后扫一遍值域使每个值域上的位置存小于等于它的最大值。接着枚举k进行处理,比较k、2k、3k…处的最大值。取模操作可以替换成减法来节省时间。

常数很大,但开了O2可以跑过去。

然后真的秀到我的一波操作出现了…题目的数据范围是100000,而数据出现了100001。重测一次我就快乐WA。

别问,问就是开大值域是好习惯。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int a[100010],ans,n,m,siz=1000,blo[100010],num,f[150][100010],sum[100010];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        blo[i]=(i-1)/siz+1;
    }
    num=blo[n];
    for(int i=1;i<=num;i++){
        memset(sum,0,sizeof(sum));
        for(int j=(i-1)*siz+1;j<=i*siz;j++){
            sum[a[j]]=a[j];
        }
        for(int j=1;j<=100001;j++){
            sum[j]=max(sum[j],sum[j-1]);
        }
        for(int k=1;k<=100001;k++){
            for(int j=0;j<=100001;j+=k){
                f[i][k]=max(f[i][k],sum[j+k-1]-j);
            }
            f[i][k]=max(f[i][k],sum[100001]%k);
        }
    }
    for(int i=1,l,r,k;i<=m;i++){
        scanf("%d%d%d",&l,&r,&k);
        ans=0;
        if(blo[l]==blo[r]){
            for(int j=l;j<=r;j++){
                ans=max(ans,a[j]%k);
            }
        }
        else{
            for(int j=l;j<=blo[l]*siz;j++){
                ans=max(ans,a[j]%k);
            }
            for(int j=(blo[r]-1)*siz+1;j<=r;j++){
                ans=max(ans,a[j]%k);
            }
            for(int j=blo[l]+1;j<blo[r];j++){
                ans=max(ans,f[j][k]);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 

T2:折射

很显然是个DP,考虑怎么设计状态。数据范围卡掉了n2,又看到每个装置向左向右这样的方向性,想到了我前不久刚刚学会的关路灯。两道题显然不一样,但我觉得第二维八成就是方向了,然后思考怎么转移。

果然我是从转移开始错的…虽然DP一直都不擅长。

正解是按x排序。设f[i][0]为当前装置为最后一个,把光线向右折射,f[i][1]为向左。按x排序以后,当前扫到的i一定x最大,它的1数组一定只会由后面的i更新,而它的0数组只会由前面的i更新。同时它的0数组会去更新前面的1数组,因为这个,第二层循环要倒序进行。x小于xi的j有可能更新f[i][0],而f[i][0]紧接着可能拿来更新x更小的f[j][1]。更新i的0数组还是用0数组更新j的1数组取决于循环到的yj与yi的大小关系。最后把所有的f[i][0]和f[i][1]加起来,因为每个i只有自己组成一种方案的时候无论向左向右都一样,每个i的总方案再减去1。

有点乱…挺玄学的,完全想不到。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
long long f[6010][2],ans,mod=1000000007;
struct node{
    int x,y;
}a[6010];
bool cmp(node a,node b){
    if(a.x<b.x)return true;
    else return false;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){
        f[i][0]=f[i][1]=1;
        for(int j=i-1;j;j--){
            if(a[j].y<a[i].y){
                f[i][1]=(f[i][1]+f[j][0])%mod;
            }
            else f[j][0]=(f[i][1]+f[j][0])%mod;
        }
//        printf("%d %d %d\n",i,f[i][1],f[i][0]);
    }
    for(int i=1;i<=n;i++){
        ans=(ans+f[i][0]+f[i][1]-1+mod)%mod;
    }
    printf("%lld",ans);
    return 0;
}
View Code

 

 

T3:画作

有一个很好想的结论,作画的每一个操作i的范围一定可以被上一个操作的范围包括。染了外面大的一圈,再把中间染回来…这样每一次都可以更新至少一个确定的位置,这个位置以后不会再被染回来造成次数浪费。

那么可以让终态的每个格子向四周连边,异色连1边表示一次操作,同色连0边。每个格子跑一次最短路,找离它最远的黑块的距离,每个这样得出的距离取min,这就是操作数最少的方案。从每个格子出发找最远的黑块等价于从这个黑块出发染到它需要几次操作,因为第一步操作一定是染黑,所以一定是找最远的黑块。同一距离的格子一定可以在同一次操作中被确定。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int r,c,ans=2147483647,vis[100010];
deque<pair<int,int> >q;
int a[51][51],b[100010];
int h[5]={0,0,-1,0,1};
int l[5]={0,-1,0,1,0};
int ver[100010],head[100010],Next[100010],edge[100010],tot;
void add(int x,int y,int z){
    ver[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
    edge[tot]=z;
}
int bfs(int x){
    int num=0;
    q.clear();
    q.push_back(make_pair(x,0));
    memset(vis,0,sizeof(vis));
    vis[x]=1;
    while(!q.empty()){
        int u=q.front().first,dis=q.front().second;
        if(b[u])num=max(num,dis);
        q.pop_front();
        for(int i=head[u];i;i=Next[i]){
            int v=ver[i],z=edge[i];
            if(!vis[v]){
                vis[v]=1;
                if(!z){
                    q.push_front(make_pair(v,dis));
                }
                else{
                    q.push_back(make_pair(v,dis+1));
                }
            }
        }
    }
//    printf("%d ",num);
    return num+1;
}
int main()
{
    scanf("%d%d",&r,&c);
    for(int i=1;i<=r;i++){
        for(int j=1;j<=c;j++){
            scanf("%1d",&a[i][j]);
            b[(i-1)*c+j]=a[i][j];
        }
    }
    for(int i=1;i<=r;i++){
        for(int j=1;j<=c;j++){
            for(int k=1;k<=4;k++){
                int x=i+h[k],y=j+l[k];
                if(x>0&&y>0&&x<=r&&y<=c){
                    add((i-1)*c+j,(x-1)*c+y,((a[i][j]==a[x][y])^1));
//                    printf("(%d,%d) (%d,%d) %d\n",i,j,x,y,((a[i][j]==a[x][y])^1));
                }
            }
        }
    }
    for(int i=1;i<=r;i++){
        for(int j=1;j<=c;j++){
            ans=min(ans,bfs((i-1)*c+j));
        }
    }
    printf("%d",ans);
    return 0;
}
View Code

 

 

大约是有史以来考得最好的一次吧,也说明我的极限大约就在这里了。

然而大家能做到的事情一定更多,希望大家能变得越来越好。

转载于:https://www.cnblogs.com/chloris/p/11571866.html

python023基于Python旅游景点推荐系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
JSP基于SSM网上医院预约挂号系统毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值