学姐学长们的测试
2018-5-26 学长学姐们决定给我们来一次测试。(milky-way,zzzyc,xMinh)
这次考试总结一下就是把能想到的错误全犯了一遍。。。。
T1:最小子段和
给定n个数,选出连续且非空的一段,使得子段和最小。内存:3MB
做这道题的时候不知道怎么想的,以为3MB只能开4个int,于是就爆了int,发现的时候已经交上去不能改了。只得了40,白丢了60分。。。
这道题我的做法很奇怪,是把所有数都取反后做最大子段和,最后输出时再取反。
# include <cstdio> # include <iostream> using namespace std; long long n,x,dp,ans=0; int main() { scanf("%lld",&n); scanf("%lld",&x); x=-x; ans=x; if(x>0) dp=x; else dp=0; for (int i=2;i<=n;i++) { scanf("%lld",&x); x=-x; if(dp>=0) dp+=x; else dp=x; ans=max(ans,dp); } printf("%lld",-ans); return 0; }
T2:
在n*m的矩阵中选出2个数,要求a在b的右方或上方或右上方,b-a最大。内存:4MB
这题错的也是很蹊跷,虽然做法没错,然而我算的是a-b。。。理论得分:100;实际得分:20;
# include <cstdio> # include <iostream> # include <cstring> using namespace std; const int inf=-1000000001; int m,n,x,col,ans=inf; int Max[1001]; int main() { for (int i=1;i<=1000;i++) Max[i]=inf; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { col=inf; for (int j=1;j<=m;j++) { scanf("%d",&x); col=max(col,Max[j]); Max[j]=max(Max[j],x); ans=max(ans,col-x); col=max(col,x); } } printf("%d",ans); return 0; }
T3:奇奇怪怪的数论
这道题的题意并不难理解,就是求x的质数因子是否也都是y的质数因子。
一开始以为gcd(x,y)=x就可以,但是9 12这组数据就会错,所以想到把x分解一下,每个质因子只乘一次,于是就有了这段非常慢非常慢的代码,后来发现如果x是个很大的质数会非常的慢。实际得分:10;
# include <cstdio>
# include <iostream>
using namespace std;
int T;
long long x,y,xx;
long long gcd(long long a,long long b)
{
return b?gcd(b,a%b):a;
}
int main()
{
scanf("%d",&T);
for (int i=1;i<=T;i++)
{
scanf("%lld%lld",&x,&y);
xx=1;
for (int j=2;x>1;++j)
{
if(x%j==0) xx*=j;
while(x%j==0) x/=j;
}
if(gcd(xx,y)==xx) printf("YES\n");
else printf("NO\n");
}
return 0;
}
T4:
本题花的时间最多,也是错的最惨的。
手画一下样例感觉像是求最长下降子序列的长度,事实上也是,因为数据范围比较大,必须写二分的NlogN做法,然而这个做法我非常不熟练,从开始想加上写写调调,拍了1300多组都没出错,差不多用了一个多小时,交上去后发了一张密码条“YES or Yes”。emmmm啊,Yes和No打成大写了。。。。改了这个就A了,然而现在是0分。
# include <cstdio> # include <iostream> # include <cstring> using namespace std; const int maxn=100001; int mid,l,r,j,T,n,k,ans,len; long long a[maxn],d[maxn]; int Find(int x) { l=0; r=len; while (l<r) { mid=(l+r)>>1; if(d[mid]>x) l=mid+1; else r=mid; } return l; } int main() { scanf("%d",&T); while (T) { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%lld",&a[i]); memset(d,-1000000001,sizeof(d)); len=1; for (int i=1;i<=n;i++) { if(a[i]<d[len]) d[++len]=a[i]; else { j=Find(a[i]); d[j]=a[i]; } } if(len>=k) printf("No\n"); else printf("Yes\n"); T--; } return 0; }
T5:
这道题要用到spj,然而spj听说并没有写出来,所以这道题就没做。
T6:找众数
出现次数超过一半的众数,卡内存;
如果两个数不一样,都删掉就好啦,剩下的就是那个众数,得了70,不知道为啥。。。赛后到luogu交了一次A了。
# include <cstdio> # include <iostream> using namespace std; int use,n; long long x,ans=0; int main() { scanf("%d",&n); while (n) { scanf("%d",&x); if(ans==0) ans=x; if(x==ans) use++; if(x!=ans) { use--; if(use==0) ans=0; } n--; } printf("%d",ans); return 0; }
一些想法:这次考试太粗心了,也可能是烧糊涂了,想得到的想不到的错误全犯了一遍,各种错误失的分加起来比实际得的分都多。以后一定要注意不能犯这种错误啊。。。
注:以上除了T1,T4改过之外其他的都是考场代码。
T3题解: