题解:

又是搜索- - 加状态压缩剪枝

二进制记下每行 每列 每个九宫格用过的数是谁 枚举的时候可以O(1)判断冲突

还有个很重要的剪枝 把可能使用数字最少的格子先搜索

代码:

 #include <cstdio>
#include <cstdlib>
#include <algorithm>
using std::sort;
const int N=,n=,val[][]={{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}};
struct info{
int x,y,z;
info(const int a=,const int b=,const int c=):
x(a),y(b),z(c){}
}im[][],v[N];
int map[][],xx[],yy[],zz[],ans,maxans,rem;
inline bool cmp(info a,info b){ return a.z>b.z || (a.z==b.z && a.x<b.x) || (a.z==b.z && a.x==b.x && a.y<b.y); }
void print(int t){
printf("%d",t);
exit();
}
void makeim(){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++){
im[i][j].x=i;
im[i][j].y=j;
if (i<=){
if (j<=) im[i][j].z=;
else if (j<=) im[i][j].z=;
else im[i][j].z=;
}else if (i<=){
if (j<=) im[i][j].z=;
else if (j<=) im[i][j].z=;
else im[i][j].z=;
}else{
if (j<=) im[i][j].z=;
else if (j<=) im[i][j].z=;
else im[i][j].z=;
}
}
}
void makexyz(){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
if (map[i][j]){
if ((xx[im[i][j].x]>>(map[i][j]-))&) print(-);
if ((yy[im[i][j].y]>>(map[i][j]-))&) print(-);
if ((zz[im[i][j].z]>>(map[i][j]-))&) print(-);
xx[im[i][j].x]|=<<(map[i][j]-);
yy[im[i][j].y]|=<<(map[i][j]-);
zz[im[i][j].z]|=<<(map[i][j]-);
}
}
void makev(){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) v[(i-)*n+j]=info(i,j,val[i][j]);
sort(v+,v+,cmp);
}
bool check(int x,int y,int z){
--z;
if ((xx[im[x][y].x]>>z)&) return ;
if ((yy[im[x][y].y]>>z)&) return ;
if ((zz[im[x][y].z]>>z)&) return ;
return ;
}
void add(int x,int y,int z,int bo){
--z;
xx[im[x][y].x]+=bo*(<<z);
yy[im[x][y].y]+=bo*(<<z);
zz[im[x][y].z]+=bo*(<<z);
}
int getsave(int t){
int res=;
for (;t;t>>=) res+=t&;
return res;
}
void search(){
if (ans+rem*<=maxans) return;
int x=,y,z=;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
if (!map[i][j]){
int save=getsave(xx[im[i][j].x]|yy[im[i][j].y]|zz[im[i][j].z]);
if (save==) return;
if (save>z) z=save,x=i,y=j;
}
if (!x){
if (maxans<ans) maxans=ans;
return;
}
for (int i=;i;i--)
if (check(x,y,i)){
rem-=i;
ans+=i*val[x][y];
add(x,y,i,);
map[x][y]=i;
search();
map[x][y]=;
add(x,y,i,-);
ans-=i*val[x][y];
rem+=i;
}
}
int main(){
rem=*;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++){
scanf("%d",&map[i][j]);
rem-=map[i][j];
ans+=map[i][j]*val[i][j];
}
makeim();
makexyz();
makev();
search();
if (maxans) print(maxans);
puts("-1");
}

【noip2009】靶形数独的更多相关文章

  1. NOIP2009靶形数独[DFS 优化]

    描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教,Z 博士拿出了他最近发明的“靶形数独 ...

  2. [NOIP2009]靶形数独 题解

    407. [NOIP2009] 靶形数独 时间限制:5 s   内存限制:128 MB [问题描述] 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低. ...

  3. [NOIP2009] 靶形数独(搜索+剪枝)

    题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的 ...

  4. NOIP2009 靶形数独

    4.靶形数独 (sudoku.pas/c/cpp) [问题描述] 小城和小华都是热爱数学的好学生, 近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了, ...

  5. NOIP2009靶形数独

    题目描述: 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的“ ...

  6. [NOIP2009] 靶形数独(搜索)

    P1074 靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士 ...

  7. NOIP2009靶形数独(暴搜)

    题目传送门 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向Z博士请教,Z博士拿出了他最近发明 ...

  8. Vijos1775 CodeVS1174 NOIP2009 靶形数独

    靶形数独 描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z博士请教, Z 博士拿出了他最近发 ...

  9. [NOIP2009] 靶形数独 骚气的大爆搜

    这两天OD留的题是搜索,这个东西,就是历年的NOIP压轴题嘛.做了几道什么斗地主啊啥的,感觉还是这题我还懂点. 这道题的搜(xia)索(da)思路是这样的:预处理出一切能处理的东西. 数独大家都了解吧 ...

  10. [NOIP2009]靶形数独 深搜+枝杈优化

    这道题,又是一位玄学搜索...... 我是用的蜗牛序搜的(顾名思义,@,这么搜),我正着搜80然后一反转比原来快了几十倍........一下AC....... 我的思路是这样的话我们可以从内到外或者从 ...

随机推荐

  1. Android支付接入(四):联通VAC计费

    原地址:http://blog.csdn.net/simdanfeg/article/details/9012031 注意事项: 1.联通支付是不需要自己标识软硬计费点的,当平台申请计费点的时候会提交 ...

  2. HDU1429+bfs+状态压缩

    bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...

  3. android 动态改变listview的内容

    本文模拟:点击一个按钮,为已有的listview添加一行数据 <?xml version="1.0" encoding="utf-8"?> < ...

  4. 【BZOJ 2453|bzoj 2120】 2453: 维护队列 (分块+二分)

    2453: 维护队列 Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有 ...

  5. http://doc.okbase.net/congcong68/archive/112508.html

    http://doc.okbase.net/congcong68/archive/112508.html

  6. 217. Contains Duplicate

    题目: Given an array of integers, find if the array contains any duplicates. Your function should retu ...

  7. 企业级 Linux 安全管理实例(1)

    公司企业多用Linux服务器,其中涉及到的一些安全管理对于安全运维人员来说是必不可少的应知技能, 以下案例沿着背景->需求->具体要求->操作步骤的流程进行描述,可以加深对安全管理的 ...

  8. Android 九宫格密码锁进入程序

    设置九宫格密码锁进入程序,设置,重置,取消等,安卓巴士地址http://www.apkbus.com/forum.php?mod=viewthread&tid=182620&extra ...

  9. 不要在头文件中使用 using namespace std;

    不要在头文件中使用(using namespace std;).   若你使用了using namespace std;,在某一头文件中,那么包含这些头文件的文件就失去了"namespace ...

  10. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析[转]

    前面在介绍Android系统的开机画面时提到,Android设备的显示屏被抽象为一个帧缓冲区,而Android系统中的SurfaceFlinger服务就是通过向这个帧缓冲区写入内容来绘制应用程序的用户 ...