http://codeforces.com/gym/101521/problem/A
题意:2*n的棋盘,有m个格子不能经过,问能否一笔画。
题解:棋盘很大,不能直接用矩阵模拟。
用数组存下每一个不能经过的坐标,按照横坐标排序。
先检查有没有发生直接堵死的情况,注意如果是最后一列或者最后几列一起被堵死了,就相当于棋盘缩短了,不影响一笔画。所以从横坐标从大到小遍历,第n列被堵死就n--。如果中间被堵死就不能一笔画退出。
然后横坐标从小到大遍历,划入一列的入口是确定的,如果没有阻碍就是1212121循环,如果正好堵住入口就不能一笔画退出,如果这一列有不能经过的格子但是没堵住,就将循环缓一步。
代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
struct node{
long long x;
int y;
}a[5005];
map<long long,bool>mp;
int cmp(node a,node b){
return a.x<b.x;
}
int main()
{
int i;
long long n;
int m;
int flag=0;
scanf("%lld%d",&n,&m);
for(i=0;i<m;i++){
scanf("%d%lld",&a[i].y,&a[i].x);
a[i].y--;
}
sort(a,a+m,cmp);
int archer;
int cnt=0;
for(i=m-1;i>=0;i--){
if(mp[a[i].x]){
if(a[i].x==n)n--;
else {
flag=1;
break;
}
}
else mp[a[i].x]=true;
}
for(i=0;i<m;i++){
if(flag)break;
if(a[i].x>n)break;
archer=(a[i].x+1+cnt)%2;
if(archer==a[i].y)flag=1;
else cnt++;
}
if(flag)printf("No\n");
else printf("Yes\n");
// cout << "Hello world!" << endl;
return 0;
}