当前位置: 代码迷 >> 综合 >> 4123: 马走日,2797:最短前缀 Trie,2362:Square 能否拼接为正方形
  详细解决方案

4123: 马走日,2797:最短前缀 Trie,2362:Square 能否拼接为正方形

热度:86   发布时间:2023-11-21 05:41:23.0

4123: 马走日 深度优先搜索 + 回溯

///马走日
int f[21][22],n,m,t; //f数组记录点有没有走过int x[10]={-2,-2,-1,1,2,2,1,-1},y[10]={-1,1,2,2,1,-1,-2,-2};//八个方向
int x1,y1,ans;
void dfs(int a,int b)   //搜索过程
{bool p=true;    //标记,判断马是否可以遍历整个棋盘for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(f[i][j]==0) //如果该点走过{p=false;   //标记为错误break; //结束内层循环}}}if(p==true) //如果可以遍历整个棋盘,就将方法数加1{ans++;return; //不用在搜下去了}for(int i=0;i<=7;i++)   //枚举马走的8个方向{int l=a+x[i];int k=b+y[i];if(f[l][k]==1)  //如果该点曾经走过,就结束当此循环continue;if(l>0&&l<=n&&k>0&&k<=m)    //判断是否越界{f[l][k]=1;   //将该点标记为1,表示不能走了dfs(l,k);       //将当前坐标作为新的起点,继续递归马要走的下一步f[l][k]=0;  //回溯}}
}int main4123() {scanf("%d",&t); //输入有多少组测试数据for(int i=1;i<=t;i++){scanf("%d %d %d %d",&n,&m,&x1,&y1); //输入起始坐标与终点坐标x1++;y1++;memset(f,0,sizeof(f));  //将f数组清空f[x1][y1]=1;    //起点不能再走ans=0;      //方案数清0dfs(x1,y1);//开始搜索,将起点的坐标作为第一个搜索的printf("%d\n",ans); //输出方案数}
}

2797:最短前缀 Trie

利用字典树实现,当节点的num为1时,说明为唯一的前缀 

//[openjudge] 2797最短前缀 Trie
struct Trie
{Trie *next[26];int num;Trie(){for (int i = 0; i < 26; i++)next[i] = NULL;num = 0;}
};
Trie root;
void insert(char *s){Trie *p = &root;for (int i = 0; s[i] ; ++i) {int tt = s[i] - 'a';if (p->next[tt]==NULL)p->next[tt] = new Trie;p = p->next[tt];p -> num++;}
}void find(char *s){Trie *p = &root;for (int i = 0; s[i] ; ++i) {int tt = s[i] - 'a';if (p->next[tt]==NULL)return;p = p->next[tt];printf("%c",s[i]);if (p->num==1)return;}
}int main2797()
{int n = 0;char word[1010][22];while (~scanf("%s", word[n])){insert(word[n]);n++;}for (int i = 0; i < n; ++i) {printf("%s ", word[i]);find(word[i]);printf("\n");}return 0;
}

2362:Square  能否拼接为正方形  DFS+回溯

// dfs时带返回值 回溯时与不带返回值的不一样,判断终止条件也不太一样
// 判断终止条件及终止条件应该有哪些变化时,只需举一个正确终止时的情况去判断

int visit[99999];int ave;
int number[99999];int n,m;
bool dfs_square(int sum , int index , int cnt){if (sum == ave){cnt ++;if (cnt==3)return true;sum = 0;//搜索成功某一条边时,要初始化sum和indexindex = 0;}for (int i = index; i < m; ++i) {if (sum + number[i]>ave)break;if (!visit[i]){visit[i] = 1;if(dfs_square(sum + number[i],i+1,cnt))return true;visit[i] = 0;//注意,搜索失败,回溯}}return false;
}int square(){cin>>n;while (n--){cin >> m;int sum = 0;for (int i = 0;i<m;i++){cin>>number[i];sum += number[i];}if (sum%4)printf("no\n");else {memset(visit,0, sizeof(visit));sort(number,number + m);ave = sum / 4;if(dfs_square(0,0,0))printf("yes\n");elseprintf("no\n");}}return 0;
}