这道题也是一个ex的模拟题
不过他比Zamjena可爱
作为一个帅气的小哥哥,让我们一起,
开启你的模拟ex大门,C++从入门到放弃!
题目
题目描述
我又来了!我又来了!
在清晨来到儿童游乐园的时候,出题人看到了一些有趣的物体:这些物体是由金属棒组成的大小不一的立方体。
在观察这些立方体的时候,出题人想到了一个有趣的问题,下面是这个问题的二维版本(因为没有人喜欢涉及三维对象的问题):你得到一个n*n的矩形(参考正方形),矩形中的一些方格是空的,有些不是。出题人从四面八方查看这个矩形,首先,他从矩形的左边开始看,记录下第一个不为空的方格的前面有多少个空格,如果这一行没有非空方格,则记录为-1。然后,他重复前面的操作,从右边,上面和下面观察这个矩形,这样,他得到了4n个这样的数字(每个边记录n个数字),然而,某个未知恶魔破坏了这个矩形,只留下了出题人留下的数字。出题人想知道,留下的这些数字是否有意义,即通过这些数字,是否能够组成一个正方形。
输入格式
第一行包含正整数n(1≤n≤100000),表示这个正方形的边长。
第二行输入n个数字Li(-1≤Li<n),表示从左边观察时第一个到第n个数字。
第三行输入n个数字Ri(-1≤Ri<n),表示从右边观察时第一个到第n个数字。
第四行输入n个数字Ui(-1≤Ui<n),表示从上边观察时第一个到第n个数字。
第五行输入n个数字Di(-1≤Di<n),表示从下边观察时第一个到第n个数字。
输出格式
如果这些数字能组成一个正方形,输出“DA”,否则输出“NE”
样例
样例输入1
3
-1 2 0
-1 0 1
2 2 1
0 0 1
样例输出1
DA
样例输入2
3
-1 0 1
-1 2 1
-1 2 -1
1 0 -1
样例输出2
NE
题解
既然要输出DA,NE,那肯定是绑点了的,想单纯骗分很考技术!
读完题后肯定知道如果相互矛盾就是NE,不然就是DA,
没有必要去把整个矩阵给模拟构造出来,
只需要去判断四个数组条件是否相互冲突即可
接下来冲突的情况口头上讲解是比较难以理解
可以画一画样例跟着一起推帮助理解
左右,上下冲突的情况:l+r>=n,u+d>=n
证明:只有1个非空点i,那么l应该为i-1,r应该为n-i,相加是n-1,证毕
左与上下,右与上下,上与左右,下与左右,垂直冲突的情况:
以证明左与上下为例:
如果l=-1,那么这一行就都是空,
那么任何一个u,d的非空位置都不能出现在这一行上
可以把这四种情况合成一个for循环完成
因为每一个l,r,u,d是第一个非空的位置-1
这中间可能有很多个非空
我们就只能找到第一个进行判断
代码实现
因为我的代码力。。。
这道题我把n砍成了一半,里面有些许变化
#include <cstdio>
#define MAXN 100005
int n;
int l[MAXN], r[MAXN], u[MAXN], d[MAXN];
bool L[MAXN], R[MAXN], U[MAXN], D[MAXN];
int main() {scanf ( "%d", &n );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &l[i] );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &r[i] );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &u[i] );for ( int i = 1;i <= n;i ++ )scanf ( "%d", &d[i] );for ( int i = 1;i <= n;i ++ ) {if ( l[i] + r[i] >= n || u[i] + d[i] >= n ) return ! printf ( "NE" );if ( l[i] != r[i] && ( l[i] == -1 || r[i] == -1 ) ) return ! printf ( "NE" );if ( u[i] != d[i] && ( u[i] == -1 || d[i] == -1 ) ) return ! printf ( "NE" );}for ( int i = 1;i <= n / 2;i ++ ) {if ( l[i] != -1 && u[l[i] + 1] == -1 ) return ! printf ( "NE" );if ( r[i] != -1 && u[n - r[i]] == -1 ) return ! printf ( "NE" );if ( u[i] != -1 && l[u[i] + 1] == -1 ) return ! printf ( "NE" );if ( d[i] != -1 && l[n - d[i]] == -1 ) return ! printf ( "NE" );if ( l[i] != -1 && ! L[l[i]] ) {L[l[i]] = 1;if ( u[l[i] + 1] > i - 1 ) return ! printf ( "NE" );}if ( r[i] != -1 && ! R[r[i]] ) {R[r[i]] = 1;if ( u[n - r[i]] > i - 1 ) return ! printf ( "NE" );}if ( u[i] != -1 && ! U[u[i]] ) {U[u[i]] = 1;if ( l[u[i] + 1] > i - 1 ) return ! printf ( "NE" );}if ( d[i] != -1 && ! D[d[i]] ) {D[d[i]] = 1;if ( l[n - d[i]] > i - 1 ) return ! printf ( "NE" );}}for ( int i = 1;i <= n;i ++ )L[i] = R[i] = U[i] = D[i] = 0;for ( int i = n;i > n / 2;i -- ) {if ( l[i] != -1 && d[l[i] + 1] == -1 ) return ! printf ( "NE" );if ( r[i] != -1 && d[n - r[i]] == -1 ) return ! printf ( "NE" );if ( u[i] != -1 && r[u[i] + 1] == -1 ) return ! printf ( "NE" );if ( d[i] != -1 && r[n - d[i]] == -1 ) return ! printf ( "NE" );if ( l[i] != -1 && ! L[l[i]] ) {L[l[i]] = 1;if ( d[l[i] + 1] > n - i ) return ! printf ( "NE" );}if ( r[i] != -1 && ! R[r[i]] ) {R[r[i]] = 1;if ( d[n - r[i]] > n - i ) return ! printf ( "NE" );}if ( u[i] != -1 && ! U[u[i]] ) {U[u[i]] = 1;if ( r[u[i] + 1] > n - i ) return ! printf ( "NE" );}if ( d[i] != -1 && ! D[d[i]] ) {D[d[i]] = 1;if ( r[n - d[i]] > n - i ) return ! printf ( "NE" );}}printf ( "DA" );return 0;
}
我终于A了一道结论题,
过不了多久,我会再发一篇ex至极的博客,Zamjena,仙女还没A这道题
有什么问题,欢迎留言,后会有期,bye~~