NYOJ 1112 求次數
阿新 • • 發佈:2018-11-20
求次數
時間限制:1000 ms | 記憶體限制:65535 KB
難度:2
描述
題意很簡單,給一個數n 以及一個字串str,區間【i,i+n-1】 為一個新的字串,i 屬於【0,strlen(str)】如果新的字串出現過ans++,例如:acmacm n=3,那麼 子串為acm cma mac acm ,只有acm出現過
求ans;
輸入
LINE 1: T組資料(T<10)
LINE 2: n ,n <= 10,且小於strlen(str);
LINE 3:str
str 僅包含英文小寫字母 ,切長度小於10w
輸出
求 ans
樣例輸入
2
2
aaaaaaa
3
acmacm
樣例輸出
5
1
解題思路:我們需要在原字串中找到每一個子串,如果這個子串沒有出現過則放入set容器中(這裡的set的資料型別定義為string),如果出現過則進行ans++,這裡需要用到substr操作進行一個快速的賦值字串操作,避免超時。
下面簡單給大家簡單介紹一下string裡面的substr
#include<string> #include<iostream> using namespace std; int main() { string s("123456789"); string a=s.substr(1,5);//這裡的兩個引數表示起始下標和終止下標。 cout<<a<<endl; } //輸出結果為:23456
下面是AC程式碼:
#include<stdio.h> #include<string> #include<set> #include<iostream> using namespace std; char s[100000],c[10]; string s1,s2; int main() { int t,n,k,i; cin>>t; set<string>s3; while(t--) { cin>>n; scanf("%s",s); s1=s; int ans=0; for(i=0,k=0;i<=s1.size()-n;i++)//進行到字串長度減n就行了 { s2=s1.substr(i,n);//這裡考慮到時間問題我們直接用string裡面的一個操作substr來將子串賦給s2; if(s3.find(s2)!=s3.end())//如果在set容器中也就是s3中找到了這個s2子串則進行ans++; { ans++; } else { s3.insert(s2);//沒有找打則表示這是一個新的子串,並將子串插入到s3中。 } }printf("%d\n",ans); s3.clear();//進行清空set容器操作 } return 0; }
如果用for迴圈來代替substr操作會顯示時間超限問題,例如下面的程式碼就是時間超限:
#include<stdio.h>
#include<string>
#include<string.h>
#include<iostream>
using namespace std;
char s[100000],c[10];
string s1,s2;
int main()
{
int t,n,k,i,j,x;
cin>>t;
while(t--)
{
cin>>n;
scanf("%s",s);
int ans=0;
x=n;
for(i=0;i<=strlen(s)-n;i++)
{
for(j=i;j<x;j++)//這裡改為了for迴圈賦值
c[j-i]=s[j];
x++;
s2=c;
if(s1.find(s2)==-1)
s1.append(s2);
else
{
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}