[NOIp 2017] 时间复杂度
输入一整行字符串时,如果中间有空格,则不能用 scanf("%s",...)
来输入!
scanf()
会在空格处停下!
在NOIp2018 前夕终于做出了NOIp2017的题
Candy? 说这道题用栈做,其实完全可以不用栈我不会,于是用一个比较笨拙的方法:找出与每个F
配对的E
,然后从第一个循环开始处理。
利用循环结构处理并列的F
与E
,递归处理嵌套的F
与E
。
用一个集合记录变量的名字,当遇到一个新变量名字时,查询是否冲突,一个循环结束改后,及时删除这个变量名。
第一次提交时只有 37 分,输出中间结果发现 match
过程中出现问题。。。冥思苦想好久不得其解,往上一翻翻然醒悟:
match 数组应该开 MAXL=100+10 的大小,结果写成了int match[MAXN]
,只开了 20 。。。
写程序时一定要细心!!!不能再犯这种低级错误!!!
//Copyright(C)Corona.
//2018-10-29
#include <set>
#include <stack>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXL=100+10,MAXN=20;
char p[MAXL][MAXN];
int match[MAXL];
set<string> var;
inline void scanf(char cache[],char End,int maxn) {
for(int i=0; i<maxn; i++) {
char c=getchar();
if(c==End || c=='\0') {
cache[i]='\0';
return;
} else {
cache[i]=c;
}
}
cache[maxn]='\0';
}
inline void scanf(int& x,char str[]) {
x=0;int len=strlen(str),f=0;
for(int i=0;i<len;i++) {
if(str[i]<'0' || str[i]>'9') {
if(str[i]=='^') f=1;
} else {
x=x*10+str[i]-'0';
}
} x*=f;
}
inline void Match(int L,int& err) {
memset(match,-1,sizeof(match));
for(int i=0; i<L; i++)
if(p[i][0]=='F') {
int cf=1;
for(int j=i+1; j<L; j++) {
cf += (p[j][0]=='F'?1:-1);
if(!cf) {
match[i]=j;
break;
}
}
}
}
inline void getName(char pro[],string& name,string& from,string& to) {
int l=strlen(pro),cnt=0;
char a[3][MAXN];
for(int i=0; i<l; i++) {
if(pro[i]==' ') {
cnt++;
for(int j=i+1,k=0; j<=l; j++,k++) {
a[cnt-1][k]=pro[j];
if(pro[j]==' ' || pro[j]=='\0' || j==l) {
a[cnt-1][k]='\0';
break;
}
}
}
}
name=a[0];from=a[1];to=a[2];
}
inline int num(string& s) {
int n=0;
for(int i=0,m=s.length(); i<m; i++) {
n=n*10+s[i]-'0';
}
return n;
}
inline int solve(int start,int end,int& err) {
int init,in_loop=1;
string name,from,to;
if(start == -1) {
//初始化为O(1)
init=0;
} else {
//初始化为当前 F 循环的复杂度
getName(p[start],name,from,to);
if(var.count(name)) {
err=5;
} else {
var.insert(name);
}
if(from=="n" && to=="n") {
init=0;
} else if(from=="n" && to!="n") {
init=0;
in_loop=0;//未进入循环
} else if(from!="n" && to=="n") {
init=1;
} else {
init=0;
if(num(from)>num(to)) in_loop=0;
}
}
int inc=0;//初始化为O(1)
for(int i=start+1; i!=end; i++) {
if(p[i][0]=='F') {
inc=max(inc,solve(i,match[i],err));
i=match[i];
}
}
var.erase(name);
return in_loop==1?init+inc:0;
}
int main() {
int T;
cin>>T;
while(T--) {
int L;
cin>>L;
char his_ans[MAXN];
scanf(his_ans,'\n',MAXN);
int complexity,com=0;
scanf(complexity,his_ans);
int err=0,cnt=0;
for(int i=0; i<L; i++) {
scanf(p[i],'\n',MAXN);
if(p[i][0]=='F') cnt++;
else if(p[i][0]=='E') cnt--;
if(cnt<0) {
err=1;
}
}
if(cnt!=0) err=2;
else {
Match(L,err);
com=solve(-1,L,err);
}
if(err) {
printf("ERR\n");
} else {
if(com==complexity) {
printf("Yes\n");
} else {
printf("No\n");
}
}
}
return 0;
}