20200726线上模拟题解
在写这篇题解之前先吐槽一下大连的新冠肺炎疫情形势严峻,害的我们只能在网上模拟了。希望疫情快点结束吧。
昨天上午线上模拟做了三道题,但说实话由于好久不动OI我已经忘记了好多东西。所以昨天的这三道题我都是写的通俗易懂的暴力骗得部分分,先将题(骗)解(分)内(攻)容(略)写在下处:
首先概括一下题意吧。
T1:给出l和r,输出l到r内每个数的最小质因子。输入:l,r
T2:假设你位于一个n层的大楼中,大楼中有一个电梯。你现在在a楼,你想坐k次电梯。第b层是机密场所你进不去。同时,你做电梯还要遵循一个规律,就是你做电梯从x层去y层,一定要保证|x-y|<|x-b|。输入:n,a,b,k
T3:有n条鱼从左往右排成一排,第i条鱼大小为ai,保证1<=ai<=n并且互不相同。这些鱼之间会互相吃如果每条鱼比它右边的第一条鱼大,就会将它吃掉。而每条鱼在吃掉比自己小的鱼🐟之后大小不会改变,同时在同一轮中可以有鱼同时吃别的鱼并且被别的鱼所吃(emmm这是怎么做到的)。输入:n,(n行)ai。
T1:
好的我们来看一下这道题的数据范围:
·对20%的数据,l=2,r<=10
·对40%的数据,l=2,r<=1e5
·对70%的数据,l=2,r<=1e6
·对100%的数据,2<=l<=r<=1e12,r-l<=1e6
好的看到最后一个数据范围下意识的发现这道题的正解一定是滑动窗口?(不确定状)但可以本人已好久不动OI并且当时学滑动窗口的时候就没有学明白所以直接决定写部分分。
但是这题我一开始就想偏了所以连70分的分都没拿到最后只拿了50分(这个分数也很让我疑惑emmm)
分析下题,我在看到此题目的时候直接的想法是对于每个数都从2开始找它最小的质数。但是如果不题前把质数都给筛出来的话那着就是一个n√n的时间复杂度。所以要优化一下呀!
最直接的思路就是用一个O(n)线性筛来优先筛出可能的所有质数,然后再来一个O(n)的筛选便可以了
但是可惜本人已经忘了线性筛怎么写所以当时写的代码思路还不是以上思路,在此说一下我当时的思路,还望大家不要模仿。
因为最小的质因数必须是大于2的(样例里有所体现)所以我们便从2开始筛选出我们要求的一系列要求的数是不是这个数的倍数。可能有同学要问了,那我之后筛选我之前筛选过的数的倍数不就又,筛选了一遍了吗?这时候立个flag就好了。
同时其实本思路只是由于本人不会线性筛而选择的无奈之举,如果能提前用欧拉筛把可能的质数都筛出来的话就能够大大降低代码的时间复杂度。
代码如下:
#include<bits/stdc++.h> #define N 10000010 using namespace std; int a[N],b[N]; int l,r,t; int main(){ freopen("factor.in","r",stdin); freopen("factor.out","w",stdout); scanf("%d%d",&l,&r); a[1]=1; for(int i=2;i<=r;i++){ for(int j=1;i*j<=r;j++){ if(!b[i*j]){ a[i*j]=i; b[i*j]=true; } } } for(int i=l;i<=r;i++){ printf("%d\n",a[i]); } return 0; }
什么?你问我正解在哪里?
T2:
数据范围:
·对40%的数据,n<=10,k<=5
·对70%的数据,n,k<=200
·对100%的数据,1<=a,b<=n<=2000,k<=2000,a≠b
一看到这题别的都不想了真的不会,直接dfs吧
(别人还有用bfs做的我没太理解但本质上貌似区别不大)
上代码(40分):
#include<bits/stdc++.h> #define esp 1000000007 using namespace std; int n,a,b,k; long long ans; void dfs(int t,int x,int y){ int dd=abs(x-y); if(t==0){ ans++;return ; } if(x>=y+1){ for(int i=y+1;i<min(n+1,x+dd);i++){ if(i!=x) dfs(t-1,i,y); } } else{ if(x<=y-1){ for(int i=y-1;i>max(0,x-dd);i--){ if(i!=x) dfs(t-1,i,y); } } } return ; } int main(){ freopen("jump.in","r",stdin); freopen("jump.out","w",stdout); scanf("%d%d%d%d",&n,&a,&b,&k); dfs(k,a,b); printf("%d",ans); return 0; }
T3:
数据范围:
·对40%的数据,n<=1000
·对100%的数据,1<=n<=1e5
`均匀分布着一半的数据保证所有的ai是完全随机形成的
直接就模拟?
说句实话这题我思路也不是很清晰改了很长时间才把样例改对,最后也只得了80分.......疑惑
上代码:
#include<bits/stdc++.h> #define N 100010 using namespace std; int n,a[N],tmp[N],ans; void dfs(){ bool yes=false; for(int i=1;i<=n;i++) tmp[i]=a[i]; for(int i=n;i>1;i--){ if(tmp[i]<a[i-1]){ tmp[i]=0; yes=true; } } if(!yes) return ; ans++; int temp=0; for(int i=1;i<=n;i++){ if(tmp[i]!=0&&a[i]!=a[i-1]){ temp=tmp[i]; } if(tmp[i]==0||a[i]==a[i-1]){ tmp[i]=temp; } } for(int i=1;i<=n;i++) a[i]=tmp[i]; dfs(); return ; } int main(){ freopen("eat.in","r",stdin); freopen("eat.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } dfs(); printf("%d",ans); return 0; }