题目如下:
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define size 1000
int check(char* v, char *h)
{
int lv = strlen(v);
int lh = strlen(h);
for(int i=0; i<lh-lv+1; i++)//every human's//little but grrrrreat change!
{
for(int j=0; j<lv; j++)//every vir's
{
if(v[j] == h[i])
{
int hi = i, hj = j, count = 0;
for(count = 0; count < lv; )
{
if(hi > (lh - 1)) return -1;
hj %= lv;
if(h[hi] == v[hj])
{
hi++; hj++; count++;
}
else break;
}
if(count == lv) return 0;//positive
}
}
}
}
int main()
{
char vir[size], human[size];
int n;
scanf("%d\n", &n );
for(int i=0; i<n; i++)
{
scanf("%s %s", &vir, &human); if(i!=n-1) scanf("\n");
int re = check(vir, human);
if(re == 0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
关于代码优化:
一开始有两个测试点出现“段错误”, 修改数组大小无果后,感觉应该是程序暴力for循环求解导致时间复杂度太大。
后面就想怎么降低不必要的过程,实际上就是跳出程序本身去思考题目蕴含了哪些关系,可以利用以优化代码,如提前结束循环过程。
后面我想到一个,就是将遍历人的DNA的for循环的结束条件由 " i<lh " 改为" i<lh-lv+1 ",如下:
//for(int i=0; i<lh; i++)
for(int i=0; i<lh-lv+1; i++)
背后的逻辑就是:当病毒的DNA开始与人的DNA重合时,如果人的DNA的剩余长度都比病毒的长度要小,那么匹配失败的结局是必然的,就不需要进行后面的操作了,于是可以提前结束程序。
结果让人惊喜,直接就AC啦~。
希望能给你带来启发~