蒟蒻为了鼓励自己学习写题解了();
C - Error Correction
题意:修改少于等于1次使得t==t',可以就yes,不然就no;
感觉代码还是非常直接的();
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
string s,s1;
vector<int>v;
int main()
{
cin>>n;
cin>>s;
int cnt=0;
int len=s.size();
for(int i=1;i<=n;i++)
{
cin>>s1;
int l=s1.size();
int flag=0;
int sign=0;
if(s1==s)flag=1;
else if(l==len)
{
for(int j=0;j<l;j++)
{
if(s[j]!=s1[j])
{
sign++;
if(sign>=2)break;
}
}
if(sign<=1)flag=1;
}else if(l==len+1)
{
int j=0,t=0;
while(j<l&&t<len)
{
if(s[t]!=s1[j])
{
t--;
sign++;
if(sign>=2)break;
}
t++;
j++;
}
if(sign<=1)flag=1;
}else if(l==len-1)
{
int j=0,t=0;
while(j<l&&t<len)
{
if(s[t]!=s1[j])
{
j--;
sign++;
if(sign>=2)break;
}
t++;
j++;
}
if(sign<=1)flag=1;
}
if(flag)
{
v.push_back(i);
cnt++;
}
}
cout<<cnt<<"\n";
for(int i:v)
{
cout<<i<<" ";
}
}
D - Square Permutation
题意:给你一串数字,交换位置,是这个数成为平方数,计算有几种可能;
当时想的是直接把数字全排列然后暴力计算。
果然tle是非常简单的事情捏();
tle代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[15];
map<ll,ll>sm;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
char x;
cin>>x;
a[i]=x-'0';
}
sort(a+1,a+n+1);
int cnt=0;
do
{
ll sum=0,k=1;
for(int i=1;i<=n;i++)
{
sum+=a[i]*k;
k=k*10;
}
//cout<<sum<<endl;
if(sm[sum])continue;
if(sqrt(sum)==(int)sqrt(sum))
{
cnt++;
sm[sum]=1;
}
} while (next_permutation(a+1,a+n+1));
cout<<cnt;
}
增加一点点思考。
数据范围最多是1e14,我们可以直接枚举平方数,只需要1e7;
统计一下我们手头上有的字符串的数字有多少,然后判断这个数能不能和我们手上的数字数量相符合,如果可以的话就OK;
然后wa了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[15];
ll cnt=0;
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
char x;
cin>>x;
a[x-'0']++;
}
for(int i=1;i<=sqrt(1e14);i++)
{
ll b[11]={0};
ll sum=i*i;
int j=0;
while(j<n)
{
b[sum%10]++;
sum/=10;
j++;
}
if(sum%10!=0)break;
int f=0;
for(int t=0;t<10;t++)
{
if(a[t]!=b[t])
{
f=1;
}
}
if(!f)cnt++;
}
cout<<cnt;
}
我这样判断sum会出问题的(可能长度非常的大但是末尾是0?);
修改了一下判断方式,直接用j来判断sum长度,如果大于n就可以直接退出了。
小于的话可能前面都是0,所以在b[0]中加上j和n的差值;
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[15];
ll cnt;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
char x;
cin>>x;
a[x-'0']++;
}
ll len=pow(10,n);
for(ll i=0;i<=sqrt(len);i++)
{
ll b[11]={0};
ll sum=i*i;
int j=0;
while(sum)
{
b[sum%10]++;
sum/=10;
j++;
}
if(j>n)break;
b[0]+=n-j;
int f=0;
for(int t=0;t<10;t++)
{
if(a[t]!=b[t])
{
f=1;
}
}
if(!f)cnt++;
}
cout<<cnt;
}
E - Joint Two Strings
题意:计算能合并出一个t字符串(不一定连续,拥有就可以)的两个字符串的数目(自己和自己可以合并);
一开始主打一个毫无想法;
首先我们找到s1 的正序和t的正序,看看前边相同的有多少个,a数组存;
然后找到 s1的倒序和t的倒序,看看后边相同的有多少个,b数组存;
然后判断a[i[+b[i]是否>=t.len;如果大于则种数增加;
tle 了;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
string s[(int)5e5+10];
string t;
int a[(int)5e5+10];
int b[(int)5e5+10];
int cal(string s1,string s2)
{
int cnt=0;
for(auto i:s1)
{
if(cnt>=s2.size())return cnt;
if(i==s2[cnt])cnt++;
}
return cnt;
}
int main()
{
cin>>n>>t;
for(int i=0;i<n;i++)
{
cin>>s[i];
a[i]=cal(s[i],t);
}
reverse(t.begin(),t.end());
for(int i=0;i<n;i++)
{
reverse(s[i].begin(),s[i].end());
b[i]=cal(s[i],t);
}
int len=t.size();
int ans=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i]+b[j]>=len)ans++;
}
}
cout<<ans;
}
我猜想是n^2太慢了。题目告诉我们字符串长度最多是5e5,所以我们完全可以搞个数组存,一下次ans就可以加好几次(运气好的话);
又tle
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
string s[(int)5e5+10];
string t;
int a[(int)5e5+10];
int b[(int)5e5+10];
int c[(int)5e5+10];
int cal(string s1,string s2)
{
int cnt=0;
for(auto i:s1)
{
if(cnt>=s2.size())return cnt;
if(i==s2[cnt])cnt++;
}
return cnt;
}
int main()
{
cin>>n>>t;
for(int i=0;i<n;i++)
{
cin>>s[i];
a[i]=cal(s[i],t);
}
reverse(t.begin(),t.end());
for(int i=0;i<n;i++)
{
reverse(s[i].begin(),s[i].end());
b[i]=cal(s[i],t);
c[b[i]]++;
}
int len=t.size();
ll ans=0;
for(int i=0;i<n;i++)
{
int l=len-a[i];
for(int j=l;j<=len;j++)
{
ans+=c[j];
}
}
cout<<ans;
}
翻阅了一下大神的代码
直接用地址传参数,效率翻倍捏(AC);
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
string s[(int)5e5+10];
string t;
int a[(int)5e5+10];
int b[(int)5e5+10];
int c[(int)5e5+10];
int cal(string &s1,string &s2)
{
int cnt=0;
for(auto i:s1)
{
if(cnt>=s2.size())return cnt;
if(i==s2[cnt])cnt++;
}
return cnt;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>t;
for(int i=0;i<n;i++)
{
cin>>s[i];
a[i]=cal(s[i],t);
}
reverse(t.begin(),t.end());
for(int i=0;i<n;i++)
{
reverse(s[i].begin(),s[i].end());
b[i]=cal(s[i],t);
c[b[i]]++;
}
int len=t.size();
ll ans=0;
for(int i=0;i<n;i++)
{
int l=len-a[i];
for(int j=l;j<=len;j++)
{
ans+=c[j];
}
}
cout<<ans;
}