题意:给你一个T,是接下来的case数。
接下来输入n,m,再输入一个n*m的矩阵。
里面有“。”,“\”,“/”,“|”,“-”,这几个。“。”表示空格。
然后叫你判断这个矩阵里面的图形是不是直线,垂线,或者斜线。
思路:找到该直线的首位置,将下面的所有位置都替换成“。”,最后再遍历整个矩阵,如果还有不是“。”的,则不正确。
这道题一开始我想复杂了。还弄了个dfs先遍历一遍找到图形都是在一起的,然后继续做,然后一直TLE,发现原来是memset(visit,0,sizeof(visit));这个函数占用时间太多了。所以果断删掉重写。
就是将搜索分成4部分。详见代码
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2005 #define inf 1<<28 using namespace std; char Map[Max][Max]; int n,m; int main() { int i,j,k,l,T; scanf("%d",&T); while(T--) { int num=0; cin>>n>>m; for(i=0; i<n; i++) { scanf("%s",Map[i]); for(j=0; j<m; j++) if(Map[i][j]!='.') { num++; break; } } if(!num)//如果num==0,证明这个矩阵全是由"。"组成的,所以直接输出错误。 { puts("INCORRECT"); continue; } char op='.'; int numx,numy; for(i=0; i<n; i++) { for(j=0; j<m; j++) { if(Map[i][j]!=op)//找到直线的首位置 { op=Map[i][j]; numx=i;//记录直线首位置的坐标 numy=j; break; } } if(op!='.') break; } bool flag=0; for(i=0; i<n; i++)//这里遍历一遍查找是否还有不同的直线的符号。 for(j=0; j<m; j++) if(Map[i][j]!='.') if(Map[i][j]!=op)//有的话标记flag=1; { flag=1; } if(flag)//如果flag=1,则证明有2个或者2和以上的直线符号在矩阵,所以直接输出错误。 { puts("INCORRECT"); continue; } i=numx,j=numy; if(Map[i][j]=='\\')//以这个直线符号为例,下同。 { while(i<n&&j<m) { if(Map[i][j]!=op) { break; } Map[i][j]='.';//如果这个位置是"\"符号,则将这个位置标记为"。"。 i++;//将遍历的点往右下角移动 j++; } } else if(Map[i][j]=='/') { while(i<n&&j>=0) { if(Map[i][j]!=op) { break; } Map[i][j]='.'; i++; j--; } } else if(Map[i][j]=='|') { while(i<n) { if(Map[i][j]!=op) { break; } Map[i][j]='.'; i++; } } else if(Map[i][j]=='-') { while(j<m) { if(Map[i][j]!=op) { break; } Map[i][j]='.'; j++; } } bool flag1=0; num=0; for(i=0; i<n; i++)//遍历一遍矩阵,如果都是"。",则说明是正确的。 { for(j=0; j<m; j++) if(Map[i][j]!='.') { flag1=1; break; } if(flag1)break; } if(!flag1) puts("CORRECT"); else puts("INCORRECT"); } return 0; }居然在这种题目上tle了这么久。而且完全是一个和主程序一点关系都没有的初始化。。。
做题还是太粗心了啊。。