FZU-1686 神龙的难题

Problem 1686 神龙的难题

Accept: 444    Submit: 1365
Time Limit: 1000 mSec    Memory Limit : 32768 KB

bubuko.com,布布扣 Problem Description

这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就要有一些人出来守护居民们不被魔物侵害.魔法使艾米莉就是这样的一个人.她骑着她的坐骑,神龙米格拉一起消灭干扰人类生存的魔物,维护王国的安定.艾米莉希望能够在损伤最小的前提下完成任务.每次战斗前,她都用时间停止魔法停住时间,然后米格拉他就可以发出火球烧死敌人.米格拉想知道,他如何以最快的速度消灭敌人,减轻艾米莉的负担.

bubuko.com,布布扣 Input

数据有多组,你要处理到EOF为止.每组数据第一行有两个数,n,m,(1<=n,m<=15)表示这次任务的地区范围. 然后接下来有n行,每行m个整数,如为1表示该点有怪物,为0表示该点无怪物.然后接下一行有两个整数,n1,m1 (n1<=n,m1<=m)分别表示米格拉一次能攻击的行,列数(行列不能互换),假设米格拉一单位时间能发出一个火球,所有怪物都可一击必杀.

bubuko.com,布布扣 Output

输出一行,一个整数,表示米格拉消灭所有魔物的最短时间.

bubuko.com,布布扣 Sample Input

4 41 0 0 10 1 1 00 1 1 01 0 0 12 24 4 0 0 0 00 1 1 00 1 1 00 0 0 02 2

bubuko.com,布布扣 Sample Output

41

bubuko.com,布布扣 Source

FOJ月赛-2009年2月- TimeLoop


重复覆盖的模板,A得第二道DLX。在精确覆盖的基础上改了好久,主要是这题时间压的比较紧。必须各种剪枝。
思路参考的别人,十分巧妙。这里直接粘贴。
把原矩阵中的1编号,一共有size个,那么建立新矩阵的列数就为size,因为原矩阵n*m,所以神龙每一次攻击攻击点一共有n*m个,这里攻击点可以看作每个攻击范围小矩阵的左上角那个点,因为攻击范围小矩阵最少是1*1, 也就是最多攻击n*m次, 所以新矩阵的行数为n*m, 也就是以攻击次数作为行,怪物的个数作为列,每一行上的1(每一次攻击)代表该攻击所能消灭的怪物,那么原问题也就转化为了 构造出来的新矩阵中最少选多少行(发动几次攻击), 这些行再组成的新矩阵中每一列至少有1个1 (因为要把所有的怪物都杀死,而且两次攻击的范围可能有重叠,一个怪物可以被两次攻击覆盖掉,也就是每列可以有多个1)。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 16*16
#define M 16*16
#define maxn 16*16*16*16
#define INF 0x3f3f3f3f
int L[maxn],R[maxn],U[maxn],D[maxn],Row[maxn],Col[maxn];
int H[N],S[M],ansn;
void init(int n,int m)
{
    for(int i=0; i<=m; i++)
    {
        S[i]=0;
        L[i]=i-1;
        R[i]=i+1;
        U[i]=D[i]=i;
    }
    L[0]=m;
    R[m]=0;
    for(int i=0; i<=n; i++)
        H[i]=-1;
}
void update(int n,int m,int t)
{
    S[m]++;
    Row[t]=n;
    Col[t]=m;
    D[t]=D[m];
    U[D[m]]=t;
    U[t]=m;
    D[m]=t;
    if(H[n]<0)
    H[n]=L[t]=R[t]=t;
    else
    {
        R[t]=R[H[n]];
        L[R[H[n]]]=t;
        L[t]=H[n];
        R[H[n]]=t;
    }
}
void Remove(int c)
{
    for(int i=D[c];i!=c;i=D[i])
    {
        L[R[i]]=L[i];
        R[L[i]]=R[i];
    }
}
void Resume(int c)
{
    for(int i=U[c];i!=c;i=U[i])
    {
        L[R[i]]=R[L[i]]=i;
    }
}
bool v[M];
int f()
{
    int a=0;
    for(int i=R[0];i!=0;i=R[i]) v[i]=true;
    for(int i=R[0];i!=0;i=R[i])
    {
        if(v[i])
        {
            a++;
            v[i]=false;
            for(int j=D[i];j!=i;j=D[j])
            {
                for(int k=R[j];k!=j;k=R[k])
                {
                    v[Col[k]]=false;
                }
            }
        }
    }
    return a;
}
void dance(int k)
{
    if(k+f()>=ansn) return;
    int c=R[0];
    if(c==0)
    {
        if(k<ansn) ansn=k;
        return;
    }
    for(int i=R[0];i!=0;i=R[i])
        if(S[i]<S[c])
            c=i;
    for(int i=D[c];i!=c;i=D[i])
    {
        Remove(i);
        for(int j=R[i];j!=i;j=R[j])
          Remove(j);
          dance(k+1);
          for(int j=L[i];j!=i;j=L[j])
            Resume(j);
            Resume(i);
    }
}
int main()
{
    int n,m,ans,t;
    int n1,m1;
    int a[16][16];
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        ans=0;
        memset (a,0,sizeof(0));
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==1)
                    {
                        a[i][j]=++ans;
                    }
            }
        }
        init(n*m,ans);
        t=ans+1;
        scanf("%d %d",&n1,&m1);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                for(int q=i;(q<=i+n1-1)&&(q<=n);q++)
                {
                    for(int w=j;(w<=j+m1-1)&&(w<=m);w++)
                    {
                        if(a[q][w]!=0)
                        {
                        update((i-1)*m+j,a[q][w],t);
                        t++;
                        }
                    }
                }
            }
        }
        ansn=INF;
        dance(0);
        printf("%d\n",ansn);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 福州大学汇编语言期末考试历年来都是以实际操作为重点,考察学生对于汇编语言的运用能力和实践经验。考试内容主要包括单项选择、填空和编程题,其中单项选择和填空题主要考察学生对汇编语言基础知识的掌握程度,编程题则主要考察学生对实际问题的处理能力。 历年考试中,编程题主题涵盖了汇编语言的各个方面,如输入输出、数学运算、条件判断、循环控制和数组操作等,涉及到实际问题的解决和编程技巧的掌握。在编程题的设计中,难度逐年升高,难度适中,涵盖的知识点也更加广泛且实用。 此外,汇编语言期末考试还会考查学生对课程中实验的理解和应用,以及对常用工具集成开发环境MASM和汇编语言程序设计流程的掌握情况。这样的设计旨在促进学生在实际运用中理解和掌握汇编语言的基本原理,提高汇编语言程序设计的能力。 总之,福州大学汇编语言期末考试历年以实际操作为主要考核方式,通过提供各种实际问题设计编程题目,考察学生对汇编语言基础知识和实践经验的掌握情况,以此检验学生的实际运用能力和应用能力。 ### 回答2: 福州大学计算机系汇编语言是一门重要的计算机基础课程,教授学生如何理解计算机内部运行机制。该课程通常在每个学期末会进行考试,最终计入学生的总成绩中。 历年来,fzu汇编语言期末考试的难度相对较高,因此学生需要花费充分的时间和精力去复习,了解考试方向和内容。在考试中,学生需要熟悉汇编语言的基本概念和常用指令,能够写出程序并进行调试。 在考试内容上,历年来的考试题目都涵盖了汇编语言的总体知识点,例如CPU结构、数据存储方式、寻址方式、编程方法、中断和I/O等。考试题型包括选择题、填空题、简答题和编程题等多种形式。 考试中的复习重点包括:CPU基本结构和运行原理、汇编语言常用指令、寻址方式和程序调试方法等。由于该课程是计算机系的入门课程,因此对于学生后续学习计算机领域的课程和研究都至关重要。 总之,fzu汇编语言期末考试历年来难度较大,需要学生投入足够的时间和精力复习考试内容。但是学好这门课程对于学生通向计算机领域和进行相关领域研究具有极为重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值