总结第九周
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了总结第九周相关的知识,希望对你有一定的参考价值。
本周结束了搜索题单,开始刷数学的三个题单和二分题单,预计14周前结束。
深搜关于地图问题:
1.注意边界。(注意使用memset的时候要考虑清楚,可能把不需要的部分也进行初始化,影响搜索)。2.不同题目的区别点在于搜索中if语句的不同,根据题意进行编写,也不是很复杂。
3.终止条件:满足便进行return返回,可能是求方案数,也可能是到达最少需要步数一类问题。
(进行回溯,将走过的点在标记为初始化状态,方便下一层循环)
模板题:P1605 迷宫
#include <bits/stdc++.h>
using namespace std;
int n,m,t,sx,sy,fx,fy,ans;
int mp[10][10],vis[10][10];
int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};
void dfs(int x,int y)
{
if(x==fx&&y==fy)
{
ans++;
return;
}
for(int i=0;i<4;i++)
{
if(vis[x+dx[i]][y+dy[i]]==0&&mp[x+dx[i]][y+dy[i]]==1)
{
vis[x][y]=1;
dfs(x+dx[i],y+dy[i]);
vis[x][y]=0;
}
}
}
int main()
{
cin>>n>>m>>t;
cin>>sx>>sy>>fx>>fy;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mp[i][j]=1;
for(int i=1;i<=t;i++)
{
int l,r;
cin>>l>>r;
mp[l][r]=0;
}
dfs(sx,sy);
cout<<ans<<endl;
return 0;
}
P1019 [NOIP2000 提高组] 单词接龙
题目要求:
1.求出可拼接长度最大的字符串。
2.一个单词最多可使用2次。
3.存在包含关系的字符串无法拼接。
思路整理:
1.因为规定了“龙”的开头,因此长度从1开始累积。
2.写一个函数返回两个字符串重叠部分的数目。
3.dfs进行遍历,对每个字符串都要考虑两次的情况。
获得重复两个字符串收尾重复元素的方法:
int rp(string s1,string s2)
{
for(int i=1;i<min(s1.length(),s2.length());i++)
{
bool f=1;
for(int j=0;j<i;j++)
{
if(s1[s1.length()-i+j]!=s2[j]) f=0;
}
if(f) return i;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n,lg,num[30];
string st[30];
int rp(string s1,string s2)
{
for(int i=1;i<min(s1.length(),s2.length());i++)
{
bool f=1;
for(int j=0;j<i;j++)
{
if(s1[s1.length()-i+j]!=s2[j]) f=0;
}
if(f) return i;
}
return 0;
}
void dfs(string s,int lg1)
{
lg=max(lg,lg1);
for(int i=0;i<n;i++)
{
if(num[i]>=2) continue;
int tmp=rp(s,st[i]);
if(tmp>0)
{
num[i]++;
dfs(st[i],lg1+st[i].length()-tmp);
num[i]--;
}
}
}
int main()
{
cin>>n;
for(int i=0;i<=n;i++)
cin>>st[i];
dfs(' '+st[n],1);
cout<<lg<<endl;
return 0;
}
可能是边界问题,最后一组数据总回报re。但加上边界,其他都能过,最后一组数据就wr了,应该是代码的一些细节问题,但就是找不出来。。。。。
#include <bits/stdc++.h>
using namespace std;
int n,d,s[105][105],c[105][2];
bool vis[105][105];
char ch[105][105];
string s1=" yizhong";
int dx[9]={0,0,0,-1,-1,-1,1,1,1};
int dy[9]={0,1,-1,0,-1,1,0,-1,1};
int dfs(int i,int j,int x,int y,int m)
{
if(m>7)
{
vis[i][j]=1;
return 1;
}
if(ch[i+x][j+y]==s1[m])
{
if(dfs(i+x,j+y,x,y,m+1))
{
vis[i][j]=1;
return 1;
}
}
}
int main()
{
freopen("in.txt","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>ch[i][j];
if(ch[i][j]=='y')
{
c[++d][0]=i;c[d][1]=j;
}
}
while(d)
{
int i=c[d][0];
int j=c[d][1];
for(int k=1;k<=8;k++)
{
if(ch[i+dx[k]][j+dy[k]]=='i')
if(dfs(i+dx[k],j+dy[k],dx[k],dy[k],3))
vis[i][j]=1;
}
d--;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(vis[i][j])
cout<<ch[i][j];
else
cout<<"*";
}
cout<<endl;
}
return 0;
}
P2404 自然数的拆分问题
将数字n一层层拆分,利用回溯遍历出多种可能。(最好去模拟一下过程 ,便于理解递归的过程)
#include <iostream>
using namespace std;
int n,a[3005]={1};
void dfs(int s,int g)
{
int i;
for(i=a[g-1];i<=s;i++)
{
if(i<n)
{
a[g]=i;
s-=i;
if(s==0)
{
for(int j=1;j<=g-1;j++)
cout<<a[j]<<"+";
cout<<a[g]<<endl;
}
else
{
dfs(s,g+1);
}
s+=i;
}
}
}
int main()
{
cin>>n;
dfs(n,1);
return 0;
}
P1596 [USACO10OCT]Lake Counting S
一道DFS判断连通块的题目。本题的技巧点在于,一般我们将遍历过为“W”的点开个数组进行标记,本题则直接将“W”变为“.”,非常巧妙。
#include <bits/stdc++.h>
using namespace std;
int n,m,ans;
char ch[105][105];
int dx[9]={0,0,0,1,1,1,-1,-1,-1};
int dy[9]={0,1,-1,0,1,-1,0,-1,1};
void dfs(int x,int y)
{
ch[x][y]='.';
for(int i=1;i<=8;i++)
{
if(x+dx[i]>=1&&x+dx[i]<=n&&y+dy[i]>=1&&y+dy[i]<=m&&ch[x+dx[i]][y+dy[i]]=='W')
dfs(x+dx[i],y+dy[i]);
}
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>ch[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(ch[i][j]=='W'){
dfs(i,j);
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}
涂色问题:注意边界,应该先搜索外面一圈,则的话就会出现错误(边缘处被涂色),这种情况由于边界被范围限制,会被误认为被1包裹。
void dfs(int x,int y) //两种书写递归的方式,考虑到外围的一圈,这种递归方式要从自己本身搜索
{
for(int i=0;i<=4;i++)
{
if(x+dx[i]>=0&&x+dx[i]<=n+1&&y+dy[i]>=0&&y+dy[i]<=n+1&&vis[x+dx[i]][y+dy[i]]==0)
{
vis[x][y]=1;
dfs(x+dx[i],y+dy[i]);
}
}
}
#include <bits/stdc++.h>
using namespace std;
int dx[5]={0,0,0,1,-1};
int dy[5]={0,1,-1,0,0};
int a[50][50];
int n;
void dfs(int x,int y)
{
if(x>=0 && x<=n+1 && y>=0&& y<=n+1)
{
if(a[x][y]==1||a[x][y]==3)
return ;
else
{
a[x][y]=3;
for(int i=1;i<=4;i++)
dfs(x+dx[i],y+dy[i]);
}
}
}
int main()
{
freopen("in.txt","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}以上是关于总结第九周的主要内容,如果未能解决你的问题,请参考以下文章