说实话,看到这道题的一瞬间就反应过来是道大模拟(真的恶心)
写了一两个小时的样子,最后得了 70 70 …
一边读一边处理(虽然读完在处理好像也不会超时,习惯问题罢了)
对于 ERR E R R 的情况照着题意判断就行了。
对于 F F 和 E E 的匹配,用一个计数变量(比如 tot t o t )来模拟就好,遇到 F F ,就让计数器加 1 1 (tot++
),遇到 E E ,就让计数器减 1 1 (tot--
),顺便判断一下,如果计数器为 0 0 且当前有为匹配的 E E 就直接输出 ERR E R R (if (tot == 0 && ch == 'E') printf("ERR\n");
),不知道怎么做的可以看看这道题
括号匹配
对于重复的字母,用一个 bool b o o l 数组存一下就好了(字母有自己的 ASCII A S C I I 码,可以直接作为下标)但如果只用一个数组的话,退出的操作就不好做了,于是我有用另一个 char c h a r 数组按先后顺序记录每一个循环使用的字母(不知道有没有大佬有更好的做法)used[letter[num]] = 0, letter[num --] = 0;
这样判断重复字母就好办了
if (used[now_letter] == 1) printf("ERR\n");
对于 ERR E R R 的情况,你可以有一堆的方法停下后续的操作,这里我就不详细地分析了(我是直接用一个 bool b o o l 变量判断的)
我反正是用gets
读入第一行,然后从头挨个处理出行数、复杂度(后文会将为什么要从头)复杂度直接存 n n 的幂,处理时就特判一下,有 n n 就是后面的数字,没有 n n 就直接赋为 0 0 ( n0=1 n 0 = 1 );
处理完就按行数挨行判断就好while(n--)
每行用gets
读入。鉴于前面的错误,也是从头处理。
看了看样例,时间复杂度好像是忽略了小的幂,直接取最大的幂,所以再用一个变量存最大幂。定义一个计数器,从 0 0 开始,对于计数器的处理和前文 FE F E 的匹配一样处理。保险起见,我每更新一次就取一次 max m a x (其实是懒得想怎么优化)。
这里要注意一下更新的条件:一定要存在一个 n n ,计数器才加 1 1 /减 1 1 (进不进得去一会儿再说),于是如此懒的我又加了一个数组记录哪一次是有 n n 的循环(反正空间不会超)
后来发现样例还是没过…
问题就在于循环进不进得去,由于循环中可能出现 n n ,于是我满篇地找范围,看到了
该数远大于 100 100
这…
远大于是什么鬼…
于是我写了个#define N 101
并在心里默默希望数据点不会卡这个上限
这样的话在预处理的时候,处理到 n n ,就直接赋成 N N 就好了。
最后又检查了一下,突然想起来有一种循环叫 F a n n F a n n ,而且它的时间似乎是 O(1) O ( 1 ) ,于是又加了一个特判。
感觉好像也没什么问题…但就是没有A
数字可以是多位数 so s o 使用的时候不要用下标直接访问(最开始我样例就死在这里,查了半天没看出来)(用getchar
的请默默无视)
一定要自己检查一下,样例过了并不能代表什么,尤其是这种恶心的大模拟
这次样例比较全面,还是可以查出不少错误的
可能有些思路没有讲到的,可以看看我的代码。下面直接上代码(代码比较丑QWQ)
#include
using namespace std;
#define N 101
int q;
bool used[205];
char letter_use[205];
bool isreal[205];
inline bool isnumber ( char a ) {
return ( a >= '0' && a <= '9' );
}
inline bool isn ( char a ) {
return a == 'n';
}
int main() {
//freopen("test.in","r",stdin);
scanf("%d\n",&q);
while ( q -- ) {
memset(used,0,sizeof(used));
/*register*/ int n = 0, mi = 0, real_mi = 0, Time = 0, max_mi = 0, num = 0;
char oper[20];
gets(oper);
bool ishead = 1, isfirst = 0, have_n = 0;
for ( int i = 0; i < strlen(oper);i ++ ) {
if ( oper[i] == ' ' && ishead ) {
ishead = 0;
isfirst = 1;
continue;
}
if ( oper[i] == 'n' ) have_n = 1;
if ( ishead && isdigit(oper[i]) ) {
n = n * 10 + ( oper[i] ^ 48 );
continue;
}
if ( isfirst && isdigit(oper[i]) ) {
if ( have_n == 0 )
mi = 0;
else
mi = mi * 10 + ( oper[i] ^ 48 );
continue;
}
}
bool tr = 0;
int Break = -1;
bool Break_ = 0;
while ( n -- ) {
gets(oper);
if ( ! tr ) {
char letter;
char kind;
int x = 0, y = 0;
bool issecond = 0;
bool fn = 0,sn = 0;
kind = oper[0];
letter = oper[2];
for ( int i = 4; i < strlen(oper); i ++ ) {
if( oper[i] == ' ' ) {
issecond = 1;
continue;
}
if ( ( ! issecond ) && ( isdigit(oper[i]) || oper[i] == 'n' ) ) {
if ( oper[i] == 'n') {
x = N;
fn = 1;
}
else
x = x * 10 + ( oper[i] ^ 48 );
}
else if ( issecond && ( isdigit(oper[i]) || oper[i] == 'n' ) ) {
if ( oper[i] == 'n') {
y = N;
sn = 1;
}
else
y = y * 10 + ( oper[i] ^ 48 );
}
}
if ( kind == 'F' ) {
if ( used[letter] == 1 ) {
printf("ERR\n");
tr = 1;
continue;
}
num++;
Time ++;
used[letter] = 1;
letter_use[num] = letter;
if ( ( ! fn ) && ( ! sn ) ) {
if ( x > y )
( ! Break_ ) && ( Break = Time, Break_ = 1 );
}
if ( ( ! fn ) && sn ) {
if ( x > N )
( ! Break_ ) && ( Break = Time, Break_ = 1 );
else
isreal[num] = 1, real_mi ++,max_mi = max ( max_mi, real_mi );
}
if ( fn && ( ! sn ) ) {
if ( y < N )
( ! Break_ ) && ( Break = Time, Break_ = 1 );
else
isreal[num] = 1, real_mi ++,max_mi = max ( max_mi, real_mi );
}
}
if ( kind == 'E' ) {
if ( num == 0 ) {
printf("ERR\n");
tr = 1;
continue;
}
used[letter_use[num]] = 0;
real_mi -= isreal[num];
isreal[num] = 0;
num --;
if ( num == 0 ) {
real_mi = 0;
}
}
}
if ( ! n && ! tr ) {
if ( Break + 1 )
max_mi = Break - 1;
if ( num )
printf("ERR\n");
else if ( max_mi == mi )
printf("Yes\n");
else
printf("No\n");
}
}
}
return 0;
}