| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
这样就不超时了???!!!一定是数据的缘故。必须先从尾部执行判断??!!!我下面给出自己的四个程序。两个TLE,两个AC。但是算法分析下来,时间数量级都是一样的!!!。那么,我最后得出结论:一定是数据的缘故,从后向前判断回溯备用的另一分支少,而从前向后则相反,也就是说剪枝具有方向性??!!!。所以必须先从尾部执行判断??!!!
TLE1:
#include<cstdio>
using namespace std;
bool check(char *&sub1,char *&sub2,char *&base,int j,int sub1j,int sub2j){
if(base[j]=='\0')return true;
if(sub1[sub1j]!='\0'&&base[j]==sub1[sub1j])
if(check(sub1,sub2,base,j+1,sub1j+1,sub2j)==true)
return true;
if(sub2[sub2j]!='\0'&&base[j]==sub2[sub2j])
if(check(sub1,sub2,base,j+1,sub1j,sub2j+1)==true)
return true;
return false;//////////以上IF全假才返回False!!!!!!!!!!
}
int main(){
int n;
char *sub1=new char[201],*sub2=new char[201],*base=new char[401];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s %s %s",sub1,sub2,base);
if(check(sub1,sub2,base,0,0,0)==true)///////从检查base第一个字符开始
printf("Data set %d: yes\n",i+1);
else printf("Data set %d: no\n",i+1);
}
}
AC1:
#include<cstdio>
#include<string>
using namespace std;//这样就不超时了???!一定是数据的缘故。必须先从尾部执行判断??!
bool check(char *&sub1,char *&sub2,char *&base,int j,int sub1j,int sub2j){
if(j<0)return true;
if(sub1j>=0&&base[j]==sub1[sub1j])
if(check(sub1,sub2,base,j-1,sub1j-1,sub2j)==true)
return true;
if(sub2j>=0&&base[j]==sub2[sub2j])
if(check(sub1,sub2,base,j-1,sub1j,sub2j-1)==true)
return true;
return false;//////////以上IF全假才返回False!!!!!!!!!!
}
int main(){
int n;
char *sub1=new char[201],*sub2=new char[201],*base=new char[401];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s %s %s",sub1,sub2,base);
int j=strlen(base),sub1j=strlen(sub1),sub2j=strlen(sub2);///末尾加一者
if(check(sub1,sub2,base,j-1,sub1j-1,sub2j-1)==true)///////从检查base第一个字符开始
printf("Data set %d: yes\n",i+1);
else printf("Data set %d: no\n",i+1);
}
}
TLE2:
#include<cstdio>
#include<stack>
using namespace std;////这却TLE,难道是数组引用不好base[j]!='\0,耗时???看来不是,从前面开始搜查,就是会比从后面慢很多????????!
struct next{
int j,sub1j,sub2j;
next(int i,int sub1i,int sub2i):j(i),sub1j(sub1i),sub2j(sub2i){};
};
bool check(char *&sub1,char *&sub2,char *&base,int i,int sub1i,int sub2i){///////栈回溯
stack<next*> Stack;
int j=0,sub1j=0,sub2j=0;
while(j<i){
if(base[j]==sub1[sub1j]&&base[j]==sub2[sub2j]){///备用的另一分支,
next *temp=new next(j+1,sub1j,sub2j+1);//因为SUB1的先执行,所以备用为SUB2者
Stack.push(temp);
j++;sub1j++;//SUB1的先执行
continue;
}
if(sub1j<sub1i&&base[j]==sub1[sub1j]){//最后一位的下标为长度减一
j++;sub1j++;
continue;
}
if(sub2j<sub2i&&base[j]==sub2[sub2j]){
j++;sub2j++;
continue;
}
if(Stack.empty()!=true){/////上两if都不是,则跳跃回溯到最近的那个分叉点!!!有一个是则不会执行此语句
j=Stack.top()->j;sub1j=Stack.top()->sub1j;sub2j=Stack.top()->sub2j;
Stack.pop();
}
else break;///都不是,也没有备用的另一分支可回溯,则不可也
}
if(j>=i)return true;
else return false;
}
int main(){
int n;
char *sub1=new char[201],*sub2=new char[201],*base=new char[401];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s %s %s",sub1,sub2,base);
int j=strlen(base),sub1j=strlen(sub1),sub2j=strlen(sub2);///末尾加一者,长度!!!
if(check(sub1,sub2,base,j,sub1j,sub2j)==true)///////从检查base第一个字符开始
printf("Data set %d: yes\n",i+1);
else printf("Data set %d: no\n",i+1);
}
}
AC2:
#include<cstdio>
#include<stack>
using namespace std;///剪枝相对于回溯以及栈写的回溯,只用在检查不成功时才出栈,而并非每次检查都出栈!!!!!
struct next{///仅是分叉点,跳跃回溯处,两个都相等,记录而已
int j,sub1j,sub2j;
next(int i,int sub1i,int sub2i):j(i),sub1j(sub1i),sub2j(sub2i){};
};
bool check(char *&sub1,char *&sub2,char *&base,int j,int sub1j,int sub2j){///////从后面向前,则不是和第一个末尾相等就要和第二个。否则No,是为剪枝!!!!
stack<next*> Stack;
while(j>=0){
if(base[j]==sub1[sub1j]&&base[j]==sub2[sub2j]){///备用的另一分支,
next *temp=new next(j-1,sub1j,sub2j-1);//因为SUB1的先执行,所以备用为SUB2者
Stack.push(temp);
j--;sub1j--;//SUB1的先执行
continue;
}
if(sub1j>=0&&base[j]==sub1[sub1j]){
j--;sub1j--;
continue;
}
if(sub2j>=0&&base[j]==sub2[sub2j]){
j--;sub2j--;
continue;
}
if(Stack.empty()!=true){/////上两if都不是,则回溯到最近的那个分叉点!!!有一个是则不会执行此语句
j=Stack.top()->j;sub1j=Stack.top()->sub1j;sub2j=Stack.top()->sub2j;////
Stack.pop();
}
else break;////都不是,也没有备用的另一分支可回溯,则不可也
}
if(j<0)return true;
else return false;//////////以上IF全假才返回False!!!!!!!!!!
}
int main(){
int n;
char *sub1=new char[201],*sub2=new char[201],*base=new char[401];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s %s %s",sub1,sub2,base);
int j=strlen(base),sub1j=strlen(sub1),sub2j=strlen(sub2);///末尾加一者
if(check(sub1,sub2,base,j-1,sub1j-1,sub2j-1)==true)///////从检查base第一个字符开始
printf("Data set %d: yes\n",i+1);
else printf("Data set %d: no\n",i+1);
}
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator