过程
考试时就绞尽脑汁去想,但最后可能知识没学扎实,也可能运气原因,最后只考了个第五,考试结束后回头一看,倒数第二题瞬间就通透了,欲哭无泪。考试前还是要把心态调整好,考试尽力而为,不留遗憾就行。
失误
在思考倒数第二题时本来有思路,做了一次,一直输出零就慌了,然后心态没调过来,索性第五题全员骗分,要不然排名还要跌几番。所以在错了时,不要慌,徐徐渐进。
易错点
第三题纯纯广搜诱捕器,模版一套就完事,但一交,Memory Limit Exceeded (36)。我一开始就蒙了,写了代码调试了一下才发现重复次数太多了,这里就需要一个memo数组记录重复,减少循环次数
但加在哪里就需要深思,每一次是对马可以跳的地方搜索,所以应该在最深一层循环判断,其余直接写就行
queue<node>q;
q.push(node(xp,yp,0));
int dx[]={-1,-2,-2,-1,1,2,2,1},dy[]={2,1,-1,-2,2,1,-1,-2};
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=0;i<8;i++){
node p(now.x+dx[i],now.y+dy[i],now.s+1);
if(p.x>=0&&p.x<n&&p.y>=0&&p.y<n){
if(memo[p.x][p.y]) continue;
memo[p.x][p.y]=true;
if(p.x==x2&&p.y==y2) return p.s;
else q.push(p);
}
}
}
return -1;
题解
最后一题有亿点点难,老师讲后写个题解理一理。
曲线谜题
首先这么多线不可能全部都起作用,所以一定有一个规律筛选掉一些线段,那么通过画几次图可知,只有两点都在图边缘上的线才有阻拦性作用,其余都可以绕过去。所以输入先判断,筛选掉一些。
但剩下的怎么判断交叉呢?我们要转化一下,二维的计算我们肯定不行(神犇当我没说),所以要转化成线段,这时,我们将四条边拆开,再把每一条线段做以数字标记,将两个点按一定顺序排序,每一条线就变成一维上的线段了,但怎么排序呢?先参悟一下图,再看结果
拆成一维后:
在图中就可以清楚地看出有两个交叉点,因为是把四条边依次拆开所以以编号分类,再分析排法
bool cmp(node a,node b){
if(a.id==1&&b.id==1) return a.y>b.y;
if(a.id==2&&b.id==2) return a.x<b.x;
if(a.id==3&&b.id==3) return a.y<b.y;
if(a.id==4&&b.id==4) return a.x>b.x;
return a.id<b.id;
}
然后因为是判断不是算,就可以像括号序列一样用栈来判断,每一个点如果栈空,入栈,如果与栈顶数字编号相同,代表与其他线不交叉,出栈,其余则入栈,最后判断栈空就行
s.push(a[0].col);
for(int i=1;i<cnt;i++){
if(s.empty()){
s.push(a[i].col);
continue;
}
if(a[i].col==s.top()){
s.pop();
continue;
}
s.push(a[i].col);
}
if(s.empty()) printf("YES");
else printf("NO");
整体情况就是这样,其余就是细节处理,为了方便检查,用函数封装筛选和拆开操作的子操作更好
bool check(int x,int y){return x==0||x==r||y==0||y==c;}//点是否在边上
int f(int x,int y){
if(x==0) return 1;
if(x==r) return 3;
if(y==0) return 2;
if(y==c) return 4;
} //点在那一条边
最后所有步骤汇合起来就组成了超长代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
struct node{
int x,y,id,col;
}a[N];
int r,c,n,cnt;
bool cmp(node a,node b){
if(a.id==1&&b.id==1) return a.y>b.y;
if(a.id==2&&b.id==2) return a.x<b.x;
if(a.id==3&&b.id==3) return a.y<b.y;
if(a.id==4&&b.id==4) return a.x>b.x;
return a.id<b.id;
}
bool check(int x,int y){return x==0||x==r||y==0||y==c;}
int f(int x,int y){
if(x==0) return 1;
if(x==r) return 3;
if(y==0) return 2;
if(y==c) return 4;
}
stack<int>s;
int main(){
scanf("%d%d%d",&r,&c,&n);
for(int i=1;i<=n;i++){
int xi1,yi1,xi2,yi2;
scanf("%d%d%d%d",&xi1,&yi1,&xi2,&yi2);
if(check(xi1,yi1)&&check(xi2,yi2)){
a[cnt].x=xi1,a[cnt].y=yi1,a[cnt].col=i;
a[cnt].id=f(xi1,yi1);
cnt++;
a[cnt].x=xi2,a[cnt].y=yi2,a[cnt].col=i;
a[cnt].id=f(xi2,yi2);
cnt++;
}
}
sort(a,a+cnt,cmp);
s.push(a[0].col);
for(int i=1;i<cnt;i++){
if(s.empty()){
s.push(a[i].col);
continue;
}
if(a[i].col==s.top()){
s.pop();
continue;
}
s.push(a[i].col);
}
if(s.empty()) printf("YES");
else printf("NO");
}
本人蒟蒻,写得不好,请见谅