【 P3952】 时间复杂度 大模拟题解

 

题目链接

 

 

完全模拟

1.模拟结果

当我们的模拟程序执行结束时,直接执行模拟结果函数,用于比对我们的结果和数据给出的结果。

 1 bool yes(char a[],char b[])
 2 {
 3     for(int i=0;i<=6;++i)
 4         if(a[i]!=b[i])
 5             return 0;
 6     return 1;
 7 }
 8 void print()
 9 {
10     memset(o,0,sizeof(o));
11     if((no1==1&&mk==1)||(mk==0)){o[0]='O';o[1]='(';o[2]='1';o[3]=')';}
12     else
13     {
14         int mi1,mi10=0;
15         mi1=mk%10;
16         if(mk>=10)
17         {mi10=mk/10;o[0]='O';o[1]='(';o[2]='n';o[3]='^';o[4]=mi10+'0';o[5]=mi1+'0';o[6]=')';}
18         else
19         {o[0]='O';o[1]='(';o[2]='n';o[3]='^';o[4]=mi1+'0';o[5]=')';}
20     }
21     if(error){cout<<"ERR"<<endl;return;}
22     if(yes(o,ok)){cout<<"Yes"<<endl;}
23     else{cout<<"No"<<endl;}
24 }
View Code

其中mi1储存的是时间复杂度

o是我们结果的模拟,模拟出o(mi1)

ok是数据输入的时间复杂度

2.模拟读入过程

 1 void F(char,int,int,bool);
 2 void read()
 3 {
 4     char ii,xx[4],yy[4];
 5     memset(xx,0,sizeof(xx));
 6     memset(yy,0,sizeof(yy));
 7     cin>>ii>>xx>>yy;
 8     int x,y;
 9     int lenx=strlen(xx);
10     int leny=strlen(yy);
11     if(xx[0]=='n'&&yy[0]!='n')
12     {
13         x=100;
14         if(leny==2)y=(yy[0]-'0')*10+(yy[1]-'0');
15         else y=(yy[0]-'0');
16         F(ii,x,y,1);
17     }
18     else if(xx[0]!='n'&&yy[0]=='n')
19     {
20         if(lenx==2)x=(xx[0]-'0')*10+(xx[1]-'0');
21         else x=(xx[0]-'0');
22         y=100;
23         F(ii,x,y,0);
24     }
25     else
26     {
27         if(leny==2)y=(yy[0]-'0')*10+(yy[1]-'0');
28         else y=(yy[0]-'0');
29         if(lenx==2)x=(xx[0]-'0')*10+(xx[1]-'0');
30         else x=(xx[0]-'0');
31         F(ii,x,y,1);
32         no1=1;
33     }
34     
35 }
View Code

运用递归方法,对于输入的 F i j x只有三种情况。

(1) F i n x

时间复杂度要乘以n,所以直接模拟

(2) F n j x

由于n>j,之后的循环嵌套其实进不去,接下来要模拟一个上锁的过程

(3) F i j x

常数级

3.模拟程序执行过程

 1 int main()
 2 {
 3     cin>>t;
 4     for(int i=1;i<=t;++i)
 5     {    
 6         mk=0;m=0;fm=0;error=0;no1=0;unlock=1;
 7         memset(ok,0,sizeof(ok));
 8         marki.erase(marki.begin(),marki.end());
 9         cin>>l;
10         cin>>ok;
11         while(l!=0)
12         {
13             mi=0;
14             unlock=1;
15             cin>>ht;    
16             if(ht=='F')
17             {    
18                 read();
19             }
20             else if(ht=='E')
21             {
22                 error=1;
23                 l--;
24             }
25         }
26         if(fm!=0)
27         {
28             error=1;
29         }
30         print();
31         
32     }
33     return 0;
34 }
View Code

主函数中输入过程每一个小程序都输入一遍

用一个map来存变量x的使用情况

当判到F时进行读入,在F()函数中会判E

所以在主函数中当判到E时直接跳error,一定要记得l--

 1 void F(char i,int x,int y,bool o1)
 2 {
 3     if(l==1)
 4     {
 5         error=1;
 6     }l--;
 7     
 8     if(marki[i]==1)
 9     {
10         error=1;
11     }
12     marki[i]=1;
13     if(fm!=0&&fm==mi)
14     {unlock=1;}    
15     if(o1!=1){m++;}fm++;
16 
17     if(x>y)
18     {unlock=0;}
19     if(unlock)mi=max(m,mi);
20     while(l!=0)
21     {    
22         cin>>ht;
23         if(ht=='F')
24         {
25             read();
26         }
27         else if(ht=='E')
28         {
29             l--;
30             if(o1!=1)
31             {
32                 m--;
33             }
34             fm--;
35             if(m==0)
36             {    
37                 mk=max(mi,mk);
38                 mi=0;
39             }
40             marki.erase(i);
41             return;
42         }
43     }
44 }
View Code

其中的error就是各个错误过程,用了一个unlock去锁住进不去的循环

用了m去存实际除去进入循环的层数,用mi去每次取出

用了fm去存包括进不去的循环在内的层数

fm回到锁前的mi时解锁

 

完整代码

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<map>
  4 #include<stack>
  5 #include<cstring>
  6 using namespace std;
  7 map<char,bool>marki;
  8 bool error;
  9 int m,fm;
 10 int mi,mk;
 11 bool no1;
 12 char o[8];
 13 char ok[8];    
 14 int t,l;
 15 char ht;
 16 char I;
 17 int X,Y;
 18 bool unlock;
 19 bool yes(char a[],char b[])
 20 {
 21     for(int i=0;i<=6;++i)
 22         if(a[i]!=b[i])
 23             return 0;
 24     return 1;
 25 }
 26 void F(char,int,int,bool);
 27 void read()
 28 {
 29     char ii,xx[4],yy[4];
 30     memset(xx,0,sizeof(xx));
 31     memset(yy,0,sizeof(yy));
 32     cin>>ii>>xx>>yy;
 33     int x,y;
 34     int lenx=strlen(xx);
 35     int leny=strlen(yy);
 36     if(xx[0]=='n'&&yy[0]!='n')
 37     {
 38         x=100;
 39         if(leny==2)y=(yy[0]-'0')*10+(yy[1]-'0');
 40         else y=(yy[0]-'0');
 41         F(ii,x,y,1);
 42     }
 43     else if(xx[0]!='n'&&yy[0]=='n')
 44     {
 45         if(lenx==2)x=(xx[0]-'0')*10+(xx[1]-'0');
 46         else x=(xx[0]-'0');
 47         y=100;
 48         F(ii,x,y,0);
 49     }
 50     else
 51     {
 52         if(leny==2)y=(yy[0]-'0')*10+(yy[1]-'0');
 53         else y=(yy[0]-'0');
 54         if(lenx==2)x=(xx[0]-'0')*10+(xx[1]-'0');
 55         else x=(xx[0]-'0');
 56         F(ii,x,y,1);
 57         no1=1;
 58     }
 59     
 60 }
 61 void F(char i,int x,int y,bool o1)
 62 {
 63     if(l==1)
 64     {
 65         error=1;
 66     }l--;
 67     
 68     if(marki[i]==1)
 69     {
 70         error=1;
 71     }
 72     marki[i]=1;
 73     if(fm!=0&&fm==mi)
 74     {unlock=1;}    
 75     if(o1!=1){m++;}fm++;
 76 
 77     if(x>y)
 78     {unlock=0;}
 79     if(unlock)mi=max(m,mi);
 80     while(l!=0)
 81     {    
 82         cin>>ht;
 83         if(ht=='F')
 84         {
 85             read();
 86         }
 87         else if(ht=='E')
 88         {
 89             l--;
 90             if(o1!=1)
 91             {
 92                 m--;
 93             }
 94             fm--;
 95             if(m==0)
 96             {    
 97                 mk=max(mi,mk);
 98                 mi=0;
 99             }
100             marki.erase(i);
101             return;
102         }
103     }
104 }
105 void print()
106 {
107     memset(o,0,sizeof(o));
108     if((no1==1&&mk==1)||(mk==0)){o[0]='O';o[1]='(';o[2]='1';o[3]=')';}
109     else
110     {
111         int mi1,mi10=0;
112         mi1=mk%10;
113         if(mk>=10)
114         {mi10=mk/10;o[0]='O';o[1]='(';o[2]='n';o[3]='^';o[4]=mi10+'0';o[5]=mi1+'0';o[6]=')';}
115         else
116         {o[0]='O';o[1]='(';o[2]='n';o[3]='^';o[4]=mi1+'0';o[5]=')';}
117     }
118     if(error){cout<<"ERR"<<endl;return;}
119     if(yes(o,ok)){cout<<"Yes"<<endl;}
120     else{cout<<"No"<<endl;}
121 }
122 int main()
123 {
124     cin>>t;
125     for(int i=1;i<=t;++i)
126     {    
127         mk=0;m=0;fm=0;error=0;no1=0;unlock=1;
128         memset(ok,0,sizeof(ok));
129         marki.erase(marki.begin(),marki.end());
130         cin>>l;
131         cin>>ok;
132         while(l!=0)
133         {
134             mi=0;
135             unlock=1;
136             cin>>ht;    
137             if(ht=='F')
138             {    
139                 read();
140             }
141             else if(ht=='E')
142             {
143                 error=1;
144                 l--;
145             }
146         }
147         if(fm!=0)
148         {
149             error=1;
150         }
151         print();
152         
153     }
154     return 0;
155 }
Code

 

转载于:https://www.cnblogs.com/dormin/p/9975926.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值