ssoj 2279 磁力阵
说不想改最后还是向T1屈服了。。然后就de了一下午Bug。。。
虽然昨天随口扯的有点道理,正解就是迭代加深A星搜索,但实际写起来就十分难受了。
说自己的做法,略鬼畜。
每个正方形的边界上的边、每条边在哪些正方形上,都可以用一个Long Long的二进制串表示。给每个矩形编号,预处理每个矩形对应边的串,每条边对应矩形的串,每个矩形对应矩形(它的所有边对应矩形的并集,之后估价会用)。
然后就直接迭代搜索,存一个串表示现在哪些正方形处理完了,每次找出第一个没处理的正方形,枚举每条边试图处理它。用一个估价函数判断现在有没有必要继续搜:找当前状态所有未处理的正方形,把它的所有边处理掉,遇到一个就res++,若res+cnt>limit 就return 0;
几个坑点,可能只有自己会被坑。。。
1.不用二进制优化会TLE,可能是我写得比较残,T2个点。。
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<vector>
- typedef long long LL;
- using namespace std;
- int T,n,totn,k,x,xx,tot,now,nowok,e[][],sq[][],ok[],tpok[],limit;
- void clear() {
- memset(e,,sizeof(e));
- memset(sq,,sizeof(sq));
- memset(ok,,sizeof(ok));
- tot=; nowok=;
- }
- void link(int ed,int id) {
- e[ed][++e[ed][]]=id;
- sq[id][++sq[id][]]=ed;
- }
- void pre() {
- totn=;
- for(int i=;i<=n;i++) totn+=i*i;
- for(int k=;k<=n;k++)
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- if(i+k<=n&&j+k<=n)
- {
- tot++;
- for(int l=;l<=k;l++) {
- now=(i-)*(*n+)+j+l;
- link(now,tot);
- now=(i+k)*(*n+)+j+l;
- link(now,tot);
- }
- now=n+(i-)*(*n+)+j;
- link(now,tot);
- link(now+k+,tot);
- for(int l=;l<=k;l++) {
- now+=(*n+);
- link(now,tot);
- link(now+k+,tot);
- }
- }
- }
- int check(int x,int c,int li) {
- memset(tpok,,sizeof(tpok));
- int res=;
- for(int i=;i<=totn;i++)
- if(!ok[i]&&!tpok[i]) {
- res++;
- for(int j=;j<=sq[i][];j++) {
- int u=sq[i][j];
- for(int l=;l<=e[u][];l++)
- tpok[e[u][l]]=;
- }
- }
- return res;
- }
- int dfs(int cnt,int no,int lim) {
- if(cnt>lim) return ;
- if(!no) return ;
- int tp[],flag=;
- memset(tp,,sizeof(tp));
- for(int i=;i<=totn;i++) if(flag) break; else {
- if(!ok[i]){
- flag=;
- for(int j=;j<=sq[i][];j++) {
- xx=; tp[]=;
- x=sq[i][j];
- for(int l=;l<=e[x][];l++) {
- if(!ok[e[x][l]]) {tp[++tp[]]=e[x][l]; xx++;}
- ok[e[x][l]]=;
- }
- if(check(sq[i][j],cnt,lim)+cnt<=lim) {
- if(dfs(cnt+,no-xx,lim)) return ;
- }
- for(int i=;i<=tp[];i++)
- ok[tp[i]]=;
- }
- }
- }
- return ;
- }
- int main()
- {
- freopen("mag.in","r",stdin);
- freopen("mag.out","w",stdout);
- scanf("%d",&T);
- while(T--) {
- scanf("%d%d",&n,&k);
- clear();
- pre();
- for(int i=;i<=k;i++) {
- scanf("%d",&x);
- for(int j=;j<=e[x][];j++) {
- if(!ok[e[x][j]]) nowok++;
- ok[e[x][j]]=;
- }
- }
- for(limit=;limit<=;limit++) {
- if(dfs(,totn-nowok,limit)) {
- printf("%d\n",limit);
- break;
- }
- }
- }
- return ;
- }
2.搜索的时候只需要搜当前状态第一个不满足的正方形,因为其他在之后的状态中是可以搜到的,不然会T8个点。。。
3.正方形的编号,因为搜索是按编号搜的,要先编小正方形再编大的。。自行体会。。会T两个点,速度是0.2秒和10.2秒的差距。。。
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #include<cmath>
- #include<queue>
- #include<vector>
- typedef long long LL;
- using namespace std;
- int T,n,totn,k,x,xx,now,tot,nowok,sqq[][];
- LL e[],sq[],val[],st,limit,N;
- void clear() {
- memset(e,,sizeof(e));
- memset(sq,,sizeof(sq));
- memset(sqq,,sizeof(sqq));
- memset(val,,sizeof(val));
- tot=; st=;
- }
- void link(int ed,int id) {
- e[ed]|=1LL<<(id-);
- sq[id]|=1LL<<(ed-);
- sqq[id][++sqq[id][]]=ed;
- }
- void pre() {
- totn=;
- for(int i=;i<=n;i++) totn+=i*i;
- N=(1LL<<totn)-;
- for(int k=;k<=n;k++)
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- if(i+k<=n&&j+k<=n)
- {
- tot++;
- for(int l=;l<=k;l++) {
- now=(i-)*(*n+)+j+l;
- link(now,tot);
- now=(i+k)*(*n+)+j+l;
- link(now,tot);
- }
- now=n+(i-)*(*n+)+j;
- link(now,tot);
- link(now+k+,tot);
- for(int l=;l<=k;l++) {
- now+=(*n+);
- link(now,tot);
- link(now+k+,tot);
- }
- }
- for(int i=;i<=totn;i++) {
- for(int j=;j<=sqq[i][];j++) {
- val[i]|=e[sqq[i][j]];
- }
- }
- }
- int check(LL now,int c,int li) {
- int res=;
- for(int i=;i<=totn-;i++) {
- if(!(now&(1LL<<i-))) {
- res++;
- if(res+c>li) return ;
- now|=val[i];
- }
- }
- return res+c<=li;
- }
- int dfs(int cnt,LL now,int lim) {
- if(cnt>lim) return ;
- if(now==N) return ;
- LL tmp;
- if(!check(now,cnt,lim)) return ;
- int flag=;
- for(int i=;i<=totn;i++) if(flag) break; else{
- if(!(now&(1LL<<i-))){
- flag=;
- for(int j=;j<=sqq[i][];j++) {
- tmp=now|e[sqq[i][j]];
- //if(check(tmp,cnt,lim)) {
- if(dfs(cnt+,tmp,lim)) return ;
- //}
- }
- }
- }
- return ;
- }
- int main()
- {
- freopen("mag.in","r",stdin);
- freopen("mag.out","w",stdout);
- scanf("%d",&T);
- while(T--) {
- scanf("%d%d",&n,&k);
- clear();
- pre();
- for(int i=;i<=k;i++) {
- scanf("%d",&x);
- st|=e[x];
- }
- for(limit=;limit<=;limit++) {
- if(dfs(,st,limit)) {
- printf("%d\n",limit);
- break;
- }
- }
- }
- return ;
- }
AC
ssoj 2279 磁力阵的更多相关文章
- 输出 n=6 的三角数字阵(JAVA基础回顾)
package itcast.feng; import java.util.Scanner; //需求:输出 n=6 的三角数字阵 //1 //2 3 //4 5 6 //7 8 9 10 //11 ...
- [教程]怎么用百度云观看和下载"磁力链接"无需下载直接观看.
1, 打开网址 http://okbt.net/ 输入你想要看的电影名字, 点搜索,鼠标右键点击拷贝磁力链接.或者 电脑装了迅雷的话.可以直接点击.用迅雷下载. 磁力链接都是这种格式的.例: mag ...
- 开源磁力搜索爬虫dhtspider原理解析
开源地址:https://github.com/callmelanmao/dhtspider. 开源的dht爬虫已经有很多了,有php版本的,python版本的和nodejs版本.经过一些测试,发现还 ...
- (算是dp吧) 小茗的魔法阵 (fzu 2225)
http://acm.fzu.edu.cn/problem.php?pid=2225 Problem Description 在打败了易基•普罗布朗.诺姆•普罗布朗之后,小茗同学开始挑战哈德•普罗 ...
- ACdream 1214---矩阵连乘
ACdream 1214---矩阵连乘 Problem Description You might have noticed that there is the new fashion among r ...
- 合工大 OJ 1332 蛇形阵
Description 蛇形针回字阵: 如3*3: 回字阵: 7 6 5 8 1 4 9 2 3 Input 多组数据: 每一行一个正整数n(n为奇数,<26),代表n*n矩阵. Output ...
- zstu.4022.旋转数阵(模拟)
旋转数阵 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1477 Solved: 102 Description 把1到n2的正整数从左上角开始由外层 ...
- 【NOIP模拟赛】正方形大阵
正方形大阵 [问题描述] [输入格式] 第一行一个正整数n代表询问次数. 接下来n行每行一个不超过八位的小数k代表一组询问. [输出格式] 输出共n行,代表每次询问的答案:如果有无数个交点 ...
- 用ubuntu下载电影:磁力链接,torrent,迅雷链接
用ubuntu下载电影:磁力链接,torrent,迅雷链接 操作系统:Ubuntu 14.04 64位 需要软件:Ktorent, Amule 安装软件: sudo apt-get install k ...
随机推荐
- pycharm快捷键表
快捷键 作用 ctrl(command)+c 复制 ctrl+v 粘贴 ctrl+z 撤销 ctrl+x 剪切,默认整行 ctrl+a 全选 ctrl+f 查找:选中批量修改 shift+ctrl+z ...
- JS对象 字符串分割 split() 方法将字符串分割为字符串数组,并返回此数组。 语法: stringObject.split(separator,limit)
字符串分割split() 知识讲解: split() 方法将字符串分割为字符串数组,并返回此数组. 语法: stringObject.split(separator,limit) 参数说明: 注意:如 ...
- .Net Core JWT Bearer 的认证
关于JWT原理在这不多说,主要由三部分组成:Header.Payload.Signature,有兴趣自己上网了解. 1.首先创建.Net Core 一个Api项目 2.添加 JWT 配置 2.1 修改 ...
- 常见的arp欺骗
三.常见ARP欺骗形式 1.假冒ARP reply包(单播) XXX,I have IP YYY and my MAC is ZZZ! 2.假冒ARP reply包(广播) Hello everyon ...
- Python 读取本地*.txt文件 替换 内容 并保存
# r 以只读的方式打开文件,文件的描述符放在文件的开头# w 打开一个文件只用于写入,如果该文件已经存在会覆盖,如果不存在则创建新文件 #路径path = r"D:\pytho ...
- 基于vue的环信基本实时通信功能
本篇文章借鉴了一些资料,然后在这个基础上,我将环信的实现全部都集成在一个组件里面进行实现: https://blog.csdn.net/github_35631540/article/details/ ...
- bzoj 1059: [ZJOI2007]矩阵游戏 [二分图][二分图最大匹配]
Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏——矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行 ...
- AmqpException: No method found for class java.lang.String
amqpTemplate发送消息用的String,接收消息用的Message,统一消息类型就可以
- centos一些故障解决方法
1. vmware下虚拟机centos,root登录时候提示鉴定故障解决方法 - lippor - 博客园 https://www.cnblogs.com/lippor/p/5537931.html ...
- JAVA判断一个对象生存还是死亡
JAVA中判断一个对象是否死亡的算法有两种: 引用计数算法 可达性分析算法 一.引用计数算法所谓引用计数算法就是,给一个对象定义一个引用计数器,每当该对象被引用一次引用计数器就加1,如果一个对象的引用 ...