【题】【状压&搜索】NKOJ 3751 扫雷游戏

原创 2016年08月29日 17:19:57

NKOJ 3751 扫雷游戏
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 时限1000ms

问题描述
有一款有趣的手机游戏。棋盘上有n颗地雷,玩家需要至少扫掉其中的k颗雷。
每一步,玩家可以用手指在手机屏幕上划一条直线,该直线经过的地雷都会被扫除掉。
问,最少需要划几次就能扫除k颗以上的地雷?

输入格式
有两组测试数据,对于每组数据:
第一行,一个整数n,表示地雷的总数
第二含,一个整数k,表示至少需要扫掉的雷数
接下来n行,每行两个整数x和y,表示一颗地雷的坐标。

输出格式
两行,每行一个整数,表示对应数据的答案

样例输入
4
4
1 1
1 2
2 1
2 2
9
7
1 1
2 2
1 3
3 1
3 3
4 1
4 2
4 3
4 5

样例输出
2
2

提示
对于30%的数据, 1<=n<=8 , 1<=k<=n , -10000<=x,y<=10000
对于100%的数据,1<=n<=16 , 1<=k<=n , -10000<=x,y<=10000

来源 改编自uva11008

思路:
1、n较小,考虑状压。
2、f[now]表示now状态时的最小滑动数,now中1的个数即为所剩炸弹数,当所剩数小于n-k时,f[now]=0;注意当所剩数为1时,f[now]=1;注:先判=0的情况再判=1的情况!!
3、每次搜索时要枚举各个方向,并删除该直线上的所有点;所以先预处理跟i号点、j号点贡献的点的集合。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int inf=1e9;

struct fy{int a,b;};

fy w[18];
int a[18][18];
int n,k;
int f[1<<18];
//...........................................................
int dfs(int now)
{
    if(f[now]!=-1) return f[now];
    int cnt=0,e[17],to=0;
    for(int i=0,s=now;i<n;i++,s>>=1) if(s&1) e[++to]=i,cnt++;
    if(n-cnt>=k) return f[now]=0;//这句一定要在下一句之前
    if(cnt==1) return f[now]=1;
    f[now]=inf;
    for(int i=1,j;i<=to;i++)
     for(int j=i+1;j<=to;j++)
     {
        f[now]=min(dfs(now&(~a[e[i]][e[j]]))+1,f[now]);
     }
    return f[now];
}
//...........................................................
bool judge(int i,int j,int k)
{
    int x1=w[i].a-w[j].a,x2=w[j].a-w[k].a;
    int y1=w[i].b-w[j].b,y2=w[j].b-w[k].b;
    return (y1*x2==y2*x1);//避免精度差
}
//...........................................................
int main()
{   
for(int q=1;q<=2;q++)
{
    scanf("%d%d",&n,&k);
    memset(f+1,-1,4*(1<<n));
    for(int i=0;i<n;i++) scanf("%d%d",&w[i].a,&w[i].b);
    for(int i=0,j,k;i<n;i++)//预处理共线集合
     for(j=i+1;j<n;j++)
     {
        if(1==j) continue;
        for(k=n-1;k>=0;k--)
        {
            a[i][j]<<=1;
            if(judge(i,j,k)) a[i][j]++;
        }
     }
    cout<<dfs((1<<n)-1)<<endl;
    memset(a,0,sizeof(a));
}   
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

NOIP2015普及组-扫雷游戏

题目太简单,不解释: #include int main(void) { char a[101][101]; int sum[100][100]={0}; int ...
  • qq_16964363
  • qq_16964363
  • 2016年08月20日 10:59
  • 1689

NOIP2015-普及组复赛-第2题-扫雷游戏

扫雷游戏是一款十分经典的单机小游戏。在 n 行 m 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多...
  • Merry2004
  • Merry2004
  • 2017年08月13日 19:30
  • 250

状压DP入门题集锦

POJ 3254 Corn Fields 题意: 一块n*m的田,1表示这个地方可以种植,0代表这个地方不能种植。植物种植还必须满足两株植物不能相邻(横竖都不行)。问共有几种种植方法,而且当...
  • Codeblocksm
  • Codeblocksm
  • 2016年03月05日 10:52
  • 409

java 扫雷游戏源码案例项目

代码如下 import java.awt.*; import javax.swing.*; //图形计数器JCounter三位 class JCounter extends JPanel { ...
  • guangxiaove
  • guangxiaove
  • 2015年02月03日 09:59
  • 8207

java扫雷游戏源代码下载

java扫雷游戏源代码下载 源代码下载地址:http://www.zuidaima.com/share/1550463791090688.htm...
  • springmvc_springdata
  • springmvc_springdata
  • 2015年06月13日 12:31
  • 1175

(NOIP2015第二题)扫雷(mine)

2. 扫雷游戏 (mine.cpp/c/pas)   扫雷游戏是一款十分经典的单机小游戏。在 n行 m 列的雷区中有一些格子含有地雷 (称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开...
  • qq_39865575
  • qq_39865575
  • 2017年08月17日 20:01
  • 229

c++ 控制台版 扫雷游戏

白天看了一天书看累了,晚上瞅见扫雷游戏,就自己琢磨着做一个呗。想了一会,也没看别人怎么做的,大概1个多小时完成了这个简单版本的扫雷游戏,由于没怎么学过c#,界面的事情可能迟几天再做,明天要回家啦,哈哈...
  • NK_test
  • NK_test
  • 2015年07月23日 23:17
  • 2584

C#编写的扫雷游戏

我突发奇想,想用C#编写了一个扫雷游戏,在网上搜了半天,结果一无所获。 在图书馆翻了半天的书,硬着头皮把一本很厚很厚的书看完了,总之,还是觉得收获挺大。 为了能够学以致用,我开始通过C#来编写扫雷游戏...
  • qq_16635325
  • qq_16635325
  • 2015年11月01日 20:17
  • 6970

java实现扫雷游戏

java 扫雷 改进 右键标记雷
  • Limbos
  • Limbos
  • 2015年08月16日 12:16
  • 4188

最新版红包扫雷游戏

[全网独家开源源码版v10.9]2017年12月最新微信红包牛牛+pc蛋蛋+北京28+加拿大28+扫雷+接龙唯一发布,其他任何论坛或者地址均为假冒诈骗,请分清谨慎。 本站源码为原生源码的升级和完善,...
  • qq_41609151
  • qq_41609151
  • 2018年01月11日 11:55
  • 82
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【题】【状压&搜索】NKOJ 3751 扫雷游戏
举报原因:
原因补充:

(最多只允许输入30个字)