2.25错题总结
wangyichenawm · · 个人记录
T1( P1481 魔族密码)
考试思路:用find()+dp,只要find()返回值不是-1,就可以转移
时间复杂度:O(n^2 )
考试代码:
#include<bits/stdc++.h>
using namespace std;
string s[2005];
int dp[2005];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
for(int i=1;i<=n;i++)
{
dp[i]=1;
for(int j=1;j<i;j++)
if(s[i].find(s[j])!=-1)
dp[i]=max(dp[i],dp[j]+1);
}
int mx=-1e9;
for(int i=1;i<=n;i++)
mx=max(mx,dp[i]);
cout<<mx;
return 0;
}
错误原因:没考虑到是前缀,并且不能用find,不是前缀find也有返回值
正确思路:用substr()+dp,只要substr()返回值=s[j],就可以转移
时间复杂度:O(n^2 )
正确代码:
#include<bits/stdc++.h>
using namespace std;
string s[2005];
int dp[2005];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
for(int i=1;i<=n;i++)
{
dp[i]=1;
for(int j=1;j<i;j++)
if(s[i].substr(0,s[j].size())==s[j])
dp[i]=max(dp[i],dp[j]+1);
}
int mx=-1e9;
for(int i=1;i<=n;i++)
mx=max(mx,dp[i]);
cout<<mx;
return 0;
}
T3(P9122 [USACO23FEB] Stamp Grid B)
考试思路:把能盖的章都盖了,然后再判断有没有没盖上的,如果有则是盖不了的,没有就是盖的了
时间复杂度:O(tn^3 )
考试代码:
#include<bits/stdc++.h>
using namespace std;
char a[25][25],b[25][25],c[25][25];
int n,k;
void th(int x,int y)
{
bool flag1=0,flag2=0,flag3=0,flag4=0;
for(int i=x;i<=x+k-1;i++)
{
for(int j=y;j<=y+k-1;j++)
{
if(b[i-x+1][j-y+1]=='*'&&a[i][j]!='*')
flag1=1;
if(b[j-y+1][i-x+1]=='*'&&a[i][j]!='*')
flag2=1;
if(b[k-i+x-1][j-y+1]=='*'&&a[i][j]!='*')
flag3=1;
if(b[k-j+y-1][i-x+1]=='*'&&a[i][j]!='*')
flag4=1;
if(flag1==1&&flag1==flag2&&flag2==flag3&&flag3==flag4)
break;
}
}
if(flag1==0)
for(int i=x;i<=x+k-1;i++)
for(int j=y;j<=y+k-1;j++)
c[i][j]=b[i-x+1][j-y+1];
if(flag2==0)
for(int i=x;i<=x+k-1;i++)
for(int j=y;j<=y+k-1;j++)
c[i][j]=b[j-y+1][i-x+1];
if(flag3==0)
for(int i=x;i<=x+k-1;i++)
for(int j=y;j<=y+k-1;j++)
c[i][j]=b[k-i+x][j-y+1];
if(flag4==0)
for(int i=x;i<=x+k-1;i++)
for(int j=y;j<=y+k-1;j++)
c[i][j]=b[k-j+y][i-x+1];
return ;
}
void solve()
{
memset(c,0,sizeof c);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
cin>>k;
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
cin>>b[i][j];
for(int i=1;i<=n-k+1;i++)
for(int j=1;j<=n-k+1;j++)
th(i,j);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]!=a[i][j])
{
cout<<"NO\n";
return ;
}
}
}
cout<<"YES\n";
return ;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
错误原因:没打完
正确思路:同上
时间复杂度:O(tn^3 )
正确代码:
#include<bits/stdc++.h>
using namespace std;
char a[25][25],b[25][25],c[25][25];
int n,k;
void fz()
{
char d[25][25]={};
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
d[i][j]=b[j][k-i+1];
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
b[i][j]=d[i][j];
return ;
}
void ks()
{
for(int i=1;i<=n-k+1;i++)
{
for(int j=1;j<=n-k+1;j++)
{
bool flag=0;
for(int i1=i;i1<i+k;i1++)
{
for(int j1=j;j1<j+k;j1++)
{
if(a[i1][j1]!='*'&&b[i1-i+1][j1-j+1]=='*')
{
flag=1;
break;
}
}
if(flag==1)
break;
}
if(flag==0)
for(int i1=i;i1<i+k;i1++)
for(int j1=j;j1<j+k;j1++)
if(b[i1-i+1][j1-j+1]=='*')
c[i1][j1]=b[i1-i+1][j1-j+1];
}
}
}
void solve()
{
memset(c,0,sizeof c);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
cin>>k;
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
cin>>b[i][j];
for(int i=1;i<=4;i++)
{
ks();
fz();
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]!=a[i][j]&&a[i][j]=='*')
{
cout<<"NO\n";
return ;
}
}
}
cout<<"YES\n";
return ;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
return 0;
}
T4(P10483 小猫爬山)
考试思路:dfs+剪枝,边循环边模拟
时间复杂度:O(?)
考试代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,ans=1e9,a[25],b[25];
void dfs(int sd,int step)
{
if(sd>=ans)
return ;
if(step>n)
{
ans=min(ans,sd);
return ;
}
if(sd==0)
{
b[1]=a[step];
dfs(sd+1,step+1);
}
else
{
bool flag=0;
for(int i=1;i<=sd;i++)
{
if(m-b[i]>=a[step])
{
b[i]+=a[step];
flag=1;
break;
}
}
if(flag==0)
{
b[sd+1]=a[step];
dfs(sd+1,step+1);
}
else
dfs(sd,step+1);
}
return ;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
reverse(a+1,a+n+1);
dfs(0,1);
cout<<ans;
return 0;
}
错误原因:没有回溯,没有考虑多种情况
正确思路:dfs+剪枝+回溯,边循环边模拟
时间复杂度:O(?)
正确代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[35],st[35],ans=1e9,n,w;
void dfs(int u,int s)
{
if(s>n)
{
ans=min(ans,u);
return ;
}
if(u>=ans)
return ;
for(int i=1;i<=u;i++)
{
if(st[i]+a[s]<=w)
{
st[i]+=a[s];
dfs(u,s+1);
st[i]-=a[s];
}
}
st[u+1]=a[s];
dfs(u+1,s+1);
st[u+1]-=a[s];
return ;
}
signed main()
{
cin>>n>>w;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
reverse(a+1,a+n+1);
dfs(0,1);
cout<<ans;
return 0;
}
T5(P1348 Couple number)
考试思路:骗分
时间复杂度:O(1);
考试代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int a,b;
cin>>a>>b;
cout<<0<<'\n';
return 0;
}
错误原因:没时间了
正确思路:数学题,(a+b)(a-b)=a(a-b)+b(a-b)=a^2-ab+ab-b^2=a^2-b^2 ,因为(a+b),(a-b) 奇偶性相同,所以(a+b),(a-b) 要么都是奇数,要么是4的倍数
时间复杂度:O(b-a)
正确代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long a,b,ans=0;
cin>>a>>b;
for(int i=a;i<=b;i++)
if(i%2!=0||i%4==0)
ans++;
cout<<ans;
return 0;
}
T6(P8604 [蓝桥杯 2013 国 C] 危险系数)
考试思路:骗分
时间复杂度:O(1);
考试代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<2;
return 0;
}
错误原因:没时间了
正确思路:简单的图论,删除的点都跑一遍,遇到那个点就不走那个点看能不能到达,能就不是,不能就+1
时间复杂度:O(n^2 )
正确代码:
using namespace std;
vector<int>a[1005];
bool vis[1005];
int cnt=1e9,y;
void dfs(int x,int s,int sum)
{
if(x==y)
{
cnt=min(cnt,sum);
return ;
}
vis[x]=1;
for(int i=0;i<a[x].size();i++)
{
if(a[x][i]==s)
continue;
if(vis[a[x][i]]==1)
continue;
dfs(a[x][i],s,sum+1);
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
a[u].push_back(v);
a[v].push_back(u);
}
int x,ans=0;
cin>>x>>y;
for(int i=1;i<=n;i++)
{
if(i==x||i==y)
continue;
dfs(x,i,1);
if(cnt==1e9)
ans++;
cnt=1e9;
for(int j=1;j<=n;j++)
vis[j]=0;
}
cout<<ans;
return 0;
}