今天的考试状态比之前好很多,心态也更稳,最后50min左右打了第二题和第三题的暴力,但时间安排上还是有问题,T1搞了接近两个小时,后面发现错了又回去改就开始紧张,最后还是错的,如果换个做题顺序应该T1、T2都能拿更多分。
正确的时间安排应该是先把好拿的分全部拿到手,再回头去肛正解,有比较麻烦的正解思路也是先去打暴力再回头做(毕竟也不能保证正确性&能敲对)。
平时练习时一定要先自己想,看题解一定要仔细理解,自己最后要能推,还有思考别人怎么想的,我要改变那些思路才能这么想。
T1.
题面
题解
-记录4个二元组√ 枚举前半部分× 解方程× 自己的特判×
-正解思路不难想,按数据范围一推就知道的要跑O(N),因此4个二元组很好想,只枚前半部分其实也是基操,如果没想错特判的话(草稿纸上推的不严谨,也没造数据检验),方程组可能推的出可能推不出(应该推不出毕竟只枚举前半部分都没想到就推不出第一个方程),这时肯定还要优化时间复杂度,考虑xi+yi的取值也不难想,因为1.xi+yi真的是基操 2.xi,yi的值的范围很小,他们俩的和确定下来就只枚举一个。
-洛谷上有数据范围更小的原题,CF1138B
代码

#include<bits/stdc++.h> #define ri register int #define ll long long #define For(i,l,r) for(ri i=l;i<=r;i++) #define Dfor(i,r,l) for(ri i=r;i>=l;i--) using namespace std; int n,cnt0,cnt1,cnt2,cnt[3],sum; vector<int>g[3]; bool f; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } int main(){ freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); n=read(); For(i,1,n){ int x=read(),y=read(); cnt[x+y]++;sum+=y; g[x+y].push_back(i); } For(x2,0,cnt[2]){ int x1=sum-(x2<<1),x0=(n>>1)-x1-x2; if(x1>=0&&x1<=cnt[1]&&x0>=0&&x0<=cnt[0]){ For(i,0,x0-1) write(g[0][i]),printf(" "); For(i,0,x1-1) write(g[1][i]),printf(" "); For(i,0,x2-1) write(g[2][i]),printf(" "); for(ri i=x0;i<(int)g[0].size();i++) write(g[0][i]),printf(" "); for(ri i=x1;i<(int)g[1].size();i++) write(g[1][i]),printf(" "); for(ri i=x2;i<(int)g[2].size();i++) write(g[2][i]),printf(" "); f=1;break; } } if(!f){cout<<-1;return 0;} return 0; }
T2.
题面
题解
-一道我想到了状态想不出转移的dp...主要原因可能平时自己推的少,而且考试时间不够没怎么推就放弃了
-看了题解,感觉我对dp还有点误解,复习时去看博客认真理解8,这个状态我想到了但觉得没有正确性somehow,可能还对枚举有些误解吧打死不想枚举
代码
T3.