说不想改最后还是向T1屈服了。。然后就de了一下午Bug。。。

虽然昨天随口扯的有点道理,正解就是迭代加深A星搜索,但实际写起来就十分难受了。

说自己的做法,略鬼畜。

每个正方形的边界上的边、每条边在哪些正方形上,都可以用一个Long Long的二进制串表示。给每个矩形编号,预处理每个矩形对应边的串,每条边对应矩形的串,每个矩形对应矩形(它的所有边对应矩形的并集,之后估价会用)。

然后就直接迭代搜索,存一个串表示现在哪些正方形处理完了,每次找出第一个没处理的正方形,枚举每条边试图处理它。用一个估价函数判断现在有没有必要继续搜:找当前状态所有未处理的正方形,把它的所有边处理掉,遇到一个就res++,若res+cnt>limit 就return 0;

几个坑点,可能只有自己会被坑。。。

1.不用二进制优化会TLE,可能是我写得比较残,T2个点。。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<queue>
  7. #include<vector>
  8. typedef long long LL;
  9. using namespace std;
  10. int T,n,totn,k,x,xx,tot,now,nowok,e[][],sq[][],ok[],tpok[],limit;
  11. void clear() {
  12. memset(e,,sizeof(e));
  13. memset(sq,,sizeof(sq));
  14. memset(ok,,sizeof(ok));
  15. tot=; nowok=;
  16. }
  17. void link(int ed,int id) {
  18. e[ed][++e[ed][]]=id;
  19. sq[id][++sq[id][]]=ed;
  20. }
  21. void pre() {
  22. totn=;
  23. for(int i=;i<=n;i++) totn+=i*i;
  24. for(int k=;k<=n;k++)
  25. for(int i=;i<=n;i++)
  26. for(int j=;j<=n;j++)
  27. if(i+k<=n&&j+k<=n)
  28. {
  29. tot++;
  30. for(int l=;l<=k;l++) {
  31. now=(i-)*(*n+)+j+l;
  32. link(now,tot);
  33. now=(i+k)*(*n+)+j+l;
  34. link(now,tot);
  35. }
  36. now=n+(i-)*(*n+)+j;
  37. link(now,tot);
  38. link(now+k+,tot);
  39. for(int l=;l<=k;l++) {
  40. now+=(*n+);
  41. link(now,tot);
  42. link(now+k+,tot);
  43. }
  44. }
  45. }
  46. int check(int x,int c,int li) {
  47. memset(tpok,,sizeof(tpok));
  48. int res=;
  49. for(int i=;i<=totn;i++)
  50. if(!ok[i]&&!tpok[i]) {
  51. res++;
  52. for(int j=;j<=sq[i][];j++) {
  53. int u=sq[i][j];
  54. for(int l=;l<=e[u][];l++)
  55. tpok[e[u][l]]=;
  56. }
  57. }
  58. return res;
  59. }
  60. int dfs(int cnt,int no,int lim) {
  61. if(cnt>lim) return ;
  62. if(!no) return ;
  63. int tp[],flag=;
  64. memset(tp,,sizeof(tp));
  65. for(int i=;i<=totn;i++) if(flag) break; else {
  66. if(!ok[i]){
  67. flag=;
  68. for(int j=;j<=sq[i][];j++) {
  69. xx=; tp[]=;
  70. x=sq[i][j];
  71. for(int l=;l<=e[x][];l++) {
  72. if(!ok[e[x][l]]) {tp[++tp[]]=e[x][l]; xx++;}
  73. ok[e[x][l]]=;
  74. }
  75. if(check(sq[i][j],cnt,lim)+cnt<=lim) {
  76. if(dfs(cnt+,no-xx,lim)) return ;
  77. }
  78. for(int i=;i<=tp[];i++)
  79. ok[tp[i]]=;
  80. }
  81. }
  82. }
  83. return ;
  84. }
  85. int main()
  86. {
  87. freopen("mag.in","r",stdin);
  88. freopen("mag.out","w",stdout);
  89. scanf("%d",&T);
  90. while(T--) {
  91. scanf("%d%d",&n,&k);
  92. clear();
  93. pre();
  94. for(int i=;i<=k;i++) {
  95. scanf("%d",&x);
  96. for(int j=;j<=e[x][];j++) {
  97. if(!ok[e[x][j]]) nowok++;
  98. ok[e[x][j]]=;
  99. }
  100. }
  101. for(limit=;limit<=;limit++) {
  102. if(dfs(,totn-nowok,limit)) {
  103. printf("%d\n",limit);
  104. break;
  105. }
  106. }
  107. }
  108. return ;
  109. }

2.搜索的时候只需要搜当前状态第一个不满足的正方形,因为其他在之后的状态中是可以搜到的,不然会T8个点。。。

3.正方形的编号,因为搜索是按编号搜的,要先编小正方形再编大的。。自行体会。。会T两个点,速度是0.2秒和10.2秒的差距。。。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<queue>
  7. #include<vector>
  8. typedef long long LL;
  9. using namespace std;
  10. int T,n,totn,k,x,xx,now,tot,nowok,sqq[][];
  11. LL e[],sq[],val[],st,limit,N;
  12. void clear() {
  13. memset(e,,sizeof(e));
  14. memset(sq,,sizeof(sq));
  15. memset(sqq,,sizeof(sqq));
  16. memset(val,,sizeof(val));
  17. tot=; st=;
  18. }
  19. void link(int ed,int id) {
  20. e[ed]|=1LL<<(id-);
  21. sq[id]|=1LL<<(ed-);
  22. sqq[id][++sqq[id][]]=ed;
  23. }
  24. void pre() {
  25. totn=;
  26. for(int i=;i<=n;i++) totn+=i*i;
  27. N=(1LL<<totn)-;
  28. for(int k=;k<=n;k++)
  29. for(int i=;i<=n;i++)
  30. for(int j=;j<=n;j++)
  31. if(i+k<=n&&j+k<=n)
  32. {
  33. tot++;
  34. for(int l=;l<=k;l++) {
  35. now=(i-)*(*n+)+j+l;
  36. link(now,tot);
  37. now=(i+k)*(*n+)+j+l;
  38. link(now,tot);
  39. }
  40. now=n+(i-)*(*n+)+j;
  41. link(now,tot);
  42. link(now+k+,tot);
  43. for(int l=;l<=k;l++) {
  44. now+=(*n+);
  45. link(now,tot);
  46. link(now+k+,tot);
  47. }
  48. }
  49. for(int i=;i<=totn;i++) {
  50. for(int j=;j<=sqq[i][];j++) {
  51. val[i]|=e[sqq[i][j]];
  52. }
  53. }
  54. }
  55. int check(LL now,int c,int li) {
  56. int res=;
  57. for(int i=;i<=totn-;i++) {
  58. if(!(now&(1LL<<i-))) {
  59. res++;
  60. if(res+c>li) return ;
  61. now|=val[i];
  62. }
  63. }
  64. return res+c<=li;
  65. }
  66. int dfs(int cnt,LL now,int lim) {
  67. if(cnt>lim) return ;
  68. if(now==N) return ;
  69. LL tmp;
  70. if(!check(now,cnt,lim)) return ;
  71. int flag=;
  72. for(int i=;i<=totn;i++) if(flag) break; else{
  73. if(!(now&(1LL<<i-))){
  74. flag=;
  75.  
  76. for(int j=;j<=sqq[i][];j++) {
  77. tmp=now|e[sqq[i][j]];
  78. //if(check(tmp,cnt,lim)) {
  79. if(dfs(cnt+,tmp,lim)) return ;
  80. //}
  81. }
  82. }
  83. }
  84. return ;
  85. }
  86. int main()
  87. {
  88. freopen("mag.in","r",stdin);
  89. freopen("mag.out","w",stdout);
  90. scanf("%d",&T);
  91. while(T--) {
  92. scanf("%d%d",&n,&k);
  93. clear();
  94. pre();
  95. for(int i=;i<=k;i++) {
  96. scanf("%d",&x);
  97. st|=e[x];
  98. }
  99. for(limit=;limit<=;limit++) {
  100. if(dfs(,st,limit)) {
  101. printf("%d\n",limit);
  102. break;
  103. }
  104. }
  105. }
  106. return ;
  107. }

AC

ssoj 2279 磁力阵的更多相关文章

  1. 输出 n=6 的三角数字阵(JAVA基础回顾)

    package itcast.feng; import java.util.Scanner; //需求:输出 n=6 的三角数字阵 //1 //2 3 //4 5 6 //7 8 9 10 //11 ...

  2. [教程]怎么用百度云观看和下载"磁力链接"无需下载直接观看.

    1, 打开网址 http://okbt.net/  输入你想要看的电影名字, 点搜索,鼠标右键点击拷贝磁力链接.或者 电脑装了迅雷的话.可以直接点击.用迅雷下载. 磁力链接都是这种格式的.例: mag ...

  3. 开源磁力搜索爬虫dhtspider原理解析

    开源地址:https://github.com/callmelanmao/dhtspider. 开源的dht爬虫已经有很多了,有php版本的,python版本的和nodejs版本.经过一些测试,发现还 ...

  4. (算是dp吧) 小茗的魔法阵 (fzu 2225)

    http://acm.fzu.edu.cn/problem.php?pid=2225   Problem Description 在打败了易基•普罗布朗.诺姆•普罗布朗之后,小茗同学开始挑战哈德•普罗 ...

  5. ACdream 1214---矩阵连乘

    ACdream 1214---矩阵连乘 Problem Description You might have noticed that there is the new fashion among r ...

  6. 合工大 OJ 1332 蛇形阵

    Description 蛇形针回字阵: 如3*3: 回字阵: 7 6 5 8 1 4 9 2 3 Input 多组数据: 每一行一个正整数n(n为奇数,<26),代表n*n矩阵. Output ...

  7. zstu.4022.旋转数阵(模拟)

    旋转数阵 Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 1477  Solved: 102 Description 把1到n2的正整数从左上角开始由外层 ...

  8. 【NOIP模拟赛】正方形大阵

    正方形大阵 [问题描述]   [输入格式]   第一行一个正整数n代表询问次数. 接下来n行每行一个不超过八位的小数k代表一组询问. [输出格式]   输出共n行,代表每次询问的答案:如果有无数个交点 ...

  9. 用ubuntu下载电影:磁力链接,torrent,迅雷链接

    用ubuntu下载电影:磁力链接,torrent,迅雷链接 操作系统:Ubuntu 14.04 64位 需要软件:Ktorent, Amule 安装软件: sudo apt-get install k ...

随机推荐

  1. pycharm快捷键表

    快捷键 作用 ctrl(command)+c 复制 ctrl+v 粘贴 ctrl+z 撤销 ctrl+x 剪切,默认整行 ctrl+a 全选 ctrl+f 查找:选中批量修改 shift+ctrl+z ...

  2. JS对象 字符串分割 split() 方法将字符串分割为字符串数组,并返回此数组。 语法: stringObject.split(separator,limit)

    字符串分割split() 知识讲解: split() 方法将字符串分割为字符串数组,并返回此数组. 语法: stringObject.split(separator,limit) 参数说明: 注意:如 ...

  3. .Net Core JWT Bearer 的认证

    关于JWT原理在这不多说,主要由三部分组成:Header.Payload.Signature,有兴趣自己上网了解. 1.首先创建.Net Core 一个Api项目 2.添加 JWT 配置 2.1 修改 ...

  4. 常见的arp欺骗

    三.常见ARP欺骗形式 1.假冒ARP reply包(单播) XXX,I have IP YYY and my MAC is ZZZ! 2.假冒ARP reply包(广播) Hello everyon ...

  5. Python 读取本地*.txt文件 替换 内容 并保存

    # r    以只读的方式打开文件,文件的描述符放在文件的开头# w    打开一个文件只用于写入,如果该文件已经存在会覆盖,如果不存在则创建新文件 #路径path = r"D:\pytho ...

  6. 基于vue的环信基本实时通信功能

    本篇文章借鉴了一些资料,然后在这个基础上,我将环信的实现全部都集成在一个组件里面进行实现: https://blog.csdn.net/github_35631540/article/details/ ...

  7. bzoj 1059: [ZJOI2007]矩阵游戏 [二分图][二分图最大匹配]

    Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行 ...

  8. AmqpException: No method found for class java.lang.String

    amqpTemplate发送消息用的String,接收消息用的Message,统一消息类型就可以

  9. centos一些故障解决方法

    1. vmware下虚拟机centos,root登录时候提示鉴定故障解决方法 - lippor - 博客园 https://www.cnblogs.com/lippor/p/5537931.html ...

  10. JAVA判断一个对象生存还是死亡

    JAVA中判断一个对象是否死亡的算法有两种: 引用计数算法 可达性分析算法 一.引用计数算法所谓引用计数算法就是,给一个对象定义一个引用计数器,每当该对象被引用一次引用计数器就加1,如果一个对象的引用 ...