gym101915e

快来打我* 2022-04-24 11:16 246阅读 0赞
  1. #include <bits/stdc++.h>
  2. #define N 10
  3. using namespace std;
  4. int a[N][N];
  5. int n,m,k,ans=0,sum=0;
  6. map<int,pair<int,int> > mp;
  7. int xx[8]={1,1,1,0,0,-1,-1,-1};
  8. int yy[8]={0,1,-1,-1,1,0,1,-1};
  9. bool judge(int cur){
  10. int x=mp[cur].first,y=mp[cur].second;
  11. int s1=0,s2=0;
  12. for(int i=0;i<8;i++){
  13. int tx=x+xx[i];
  14. int ty=y+yy[i];
  15. if(a[tx][ty]==1) s1++;
  16. if(a[tx][ty]==2) s2++;
  17. }
  18. if(a[x][y]==2&&s1>0||a[x][y]==1&&s2<=k){
  19. return true;
  20. }else{
  21. return false;
  22. }
  23. }
  24. void dfs(int cur){
  25. int x=mp[cur].first,y=mp[cur].second;
  26. if(n*m+1-cur+sum<ans) return;
  27. if(cur>m+2){
  28. if(!judge(cur-m-2)) return;
  29. }
  30. if(cur>(n-1)*m+2){
  31. if(!judge(cur-2)) return;
  32. }
  33. if(cur==n*m+1){
  34. if(!judge(cur-m-1)) return;
  35. if(!judge(cur-1)) return;
  36. ans=max(ans,sum);
  37. return;
  38. }
  39. a[x][y]=1;
  40. dfs(cur+1);
  41. a[x][y]=0;
  42. a[x][y]=2;
  43. sum++;
  44. dfs(cur+1);
  45. sum--;
  46. a[x][y]=0;
  47. }
  48. int main(){
  49. int t;
  50. cin>>t;
  51. while(t--){
  52. int i,j,cnt=0;
  53. ans=0;
  54. sum=0;
  55. cin>>n>>m>>k;
  56. for(i=1;i<=n;i++){
  57. for(j=1;j<=m;j++){
  58. mp[++cnt]=make_pair(i,j);
  59. }
  60. }
  61. dfs(1);
  62. cout<<ans<<endl;
  63. }
  64. }

一道搜索题 我的做法是枚举到i行j列 先用map按照遍历顺序记录每个坐标编号 去判断i-1行 j-2列是否合法 也就是编号为x-m-2(思考为什么这样) 因为此时它周围的8个点已经确定 通过这种方法剪枝 到最后一行时 再对x-1进行合法检查 搜索题关键是剪枝

发表评论

表情:
评论列表 (有 0 条评论,246人围观)

还没有评论,来说两句吧...

相关阅读

    相关 gym224647B

    gym224647B 题意: > 在二维平面中·选出一个面积最小的三角形,输出这个三角形面积的两倍。 解法: > 首先,最优解一定在相邻最近的三个点...

    相关 GYM 100685 K

    乱搞题 统计每一个不是magic word的单词,然后每个make\_pair 然后按照公式计算答案。 因为这里是乱序的统计make\_pair的情况,所以如果相邻

    相关 Gym - 101201H

    ![70][] 题意:有k个区间,用他们填满1~n,不允许重叠,问留下的空隙最少是多少 思路:可以从两方面考虑,第一个是正面考虑,转移方程dp\[i\]=min(dp\[j

    相关 Gym - 101889E 记忆化搜索

    思维还是太将江华,开始一直想dp,就是这一位余数固定时取最小的一个字符串,但是字符串太大,赋值的时候超时,其实根本没必要存字符串,只要记忆化搜索,看看\[pos\]\[res\