NOIP2009靶形数独(DFS)
来源:互联网 发布:网络推广专员面试 编辑:程序博客网 时间:2024/05/21 18:33
NOIP2009靶形数独
思路1
刚看到这题,这不显然DFS么
直接爆搜了先。。。
稍微处理了下,爆搜有80分
改了半天,还没过。。
然后发现有几个货用了一个很污的方法
因为dfs超时,他们在dfs上加了句话
if(++T>=12000000) return ;
因为是在更新ans的值,这样做有可能过,而且在超时前强行return掉
(估计这个极限数字他们也试了好久)
由于数据比较水,这样还真过了,800毫秒卡了过去。。。
好方法!真的
直接超时还不如像这样碰碰运气
题解1
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define FOR(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;++i)#define DOR(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;--i)#define INF 0x3f3f3f3f#define M 100005#define N 10struct node {int x,y,v;}B[100];bool cmp(node x,node y) {return x.v<y.v;}inline void chk(int &a,int b) { if(a<b) a=b;}int sc[N][N]= { {0,0,0,0,0,0,0,0,0,0}, {0,6,6,6,6,6,6,6,6,6}, {0,6,7,7,7,7,7,7,7,6}, {0,6,7,8,8,8,8,8,7,6}, {0,6,7,8,9,9,9,8,7,6}, {0,6,7,8,9,10,9,8,7,6}, {0,6,7,8,9,9,9,8,7,6}, {0,6,7,8,8,8,8,8,7,6}, {0,6,7,7,7,7,7,7,7,6}, {0,6,6,6,6,6,6,6,6,6},};int ans,cnt,T,a;int pic[N][N];bool mark[4][N][N];inline int f(int a,int b) { a=(a-1)/3; b=(b-1)/3; return a*3+b+1;}void dfs(int s,int sum) { T++; if(T>=12000000)return ; if(s==cnt+1) { chk(ans,sum); return ; } int x=B[s].x; int y=B[s].y; int a=f(x,y); FOR(i,1,9) { if(mark[1][x][i]||mark[2][y][i]||mark[3][a][i]) continue; mark[1][x][i]=mark[2][y][i]=mark[3][a][i]=1; pic[x][y]=i; dfs(s+1,sum+i*sc[x][y]); mark[1][x][i]=mark[2][y][i]=mark[3][a][i]=0; pic[x][y]=0; }}void Init() { FOR(i,1,9)FOR(j,1,9) if(pic[i][j]) { int num=pic[i][j]; mark[1][i][num]=1; mark[2][j][num]=1; mark[3][f(i,j)][num]=1; } int &sum=a; FOR(i,1,9)FOR(j,1,9) { if(pic[i][j]==0) { cnt++; FOR(k,1,9)if(mark[1][i][k]+mark[2][j][k]+mark[3][f(i,j)][k]==0)B[cnt].v++; B[cnt].x=i,B[cnt].y=j; } else sum+=pic[i][j]*sc[i][j]; } sort(B+1,B+1+cnt,cmp);}int main() { FOR(i,1,9)FOR(j,1,9) scanf("%d",&pic[i][j]); Init(); dfs(1,a); if(ans) cout<<ans<<endl; else puts("-1"); return 0;}
思路2
当然,上述算法显然不是正解
这昨天我在帮同学调这道题的时候
小C说正解是每次dfs都找当前图中可填数字最少的位置来枚举
这样做正确性还是比较显然的
当然我下面这份代码跑的还是比较慢的
再用二进制状压一下,位运算就快多了
题解2
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#define FOR(i,a,b) for(int i=(a),i##_end_=(b);i<=i##_end_;++i)#define DOR(i,a,b) for(int i=(a),i##_end_=(b);i>=i##_end_;--i)#define INF 0x3f3f3f3f#define M 100005#define N 10struct node {int x,y;}B;inline void chk(int &a,int b) {if(a<b) a=b;}int sc[N][N]= { {0,0,0,0,0,0,0,0,0,0}, {0,6,6,6,6,6,6,6,6,6}, {0,6,7,7,7,7,7,7,7,6}, {0,6,7,8,8,8,8,8,7,6}, {0,6,7,8,9,9,9,8,7,6}, {0,6,7,8,9,10,9,8,7,6}, {0,6,7,8,9,9,9,8,7,6}, {0,6,7,8,8,8,8,8,7,6}, {0,6,7,7,7,7,7,7,7,6}, {0,6,6,6,6,6,6,6,6,6},};int ans,cnt,T;int pic[N][N];bool mark[4][N][N];inline int f(int a,int b) { a=(a-1)/3; b=(b-1)/3; return a*3+b+1;}inline node getnxt(){ node tmp; tmp=(node){0,0}; int MIN=INF; FOR(i,1,9)FOR(j,1,9) { if(pic[i][j]==0) { int cnt=0; FOR(k,1,9)if(!mark[1][i][k]&&!mark[2][j][k]&&!mark[3][f(i,j)][k])cnt++; if(cnt<MIN)MIN=cnt,tmp.x=i,tmp.y=j; } } return tmp;}void dfs(int sum) { node s=getnxt(); if(s.x==0&&s.y==0) { chk(ans,sum); return ; } int x=s.x; int y=s.y; int a=f(x,y); FOR(i,1,9) { if(mark[1][x][i]||mark[2][y][i]||mark[3][a][i]) continue; mark[1][x][i]=mark[2][y][i]=mark[3][a][i]=1; pic[x][y]=i; dfs(sum+i*sc[x][y]); mark[1][x][i]=mark[2][y][i]=mark[3][a][i]=0; pic[x][y]=0; }}void Init() { FOR(i,1,9)FOR(j,1,9) if(pic[i][j]) { int num=pic[i][j]; mark[1][i][num]=1; mark[2][j][num]=1; mark[3][f(i,j)][num]=1; }}int main() { FOR(i,1,9)FOR(j,1,9) scanf("%d",&pic[i][j]); Init(); int sum=0; FOR(i,1,9)FOR(j,1,9) sum+=pic[i][j]*sc[i][j]; dfs(sum); if(ans) cout<<ans<<endl; else puts("-1"); return 0;}
阅读全文
1 0
- NOIP2009靶形数独(DFS)
- NOIP2009 靶形数独
- NOIP2009 靶形数独
- NOIP2009 靶形数独
- NOIP2009靶形数独
- noip2009靶形数独
- noip2009靶形数独
- [noip2009]靶形数独
- noip2009 靶形数独 (搜索)
- NOIP2009靶形数独——位运算优化DFS
- 洛谷 1074 [NOIP2009] 靶形数独 dfs+剪枝
- [DLX] [NOIP2009] 靶形数独
- [NOIP2009]靶形数独【搜索】
- NOIP2009 靶形数独(搜索)
- 【[NOIP2009】靶形数独 题解
- 大暴搜 [NOIP2009]靶形数独
- 【NOIP2009】靶形数独 DLX(Dancing Links)
- noip2009 靶形数独 (代码还算不丑)
- 进程和线程的差别
- Airflow安装教程
- 高精模板
- Java基础之抽象类和接口
- 基于selenium和requests的京东商品信息和评论爬虫
- NOIP2009靶形数独(DFS)
- Linux下CMake 安装教程
- 在字符串中找出第一个只出现一次的字符,例如:输入abaccdeff,则输出b
- 深度学习进阶(一.2)--结合GPU搭建theano貌似成功了,但是测试数据运行失败
- LeetCode-105. Construct Binary Tree from Preorder and Inorder Traversal
- 探究webassembly(2):性能探究和实验分析
- UVA 12100 Printer Queue(队列,优先队列)
- volatile
- Selenium3+Python3+Firefox56配置及测试解析