• 昆特牌 解题报告


    昆特牌

    题目背景

    什么?你还有一场 NOIP 模拟赛? 什么都别说,先来盘昆特牌吧!

    题目描述

    昆特牌是一款双人对战卡牌游戏,游戏规则现简化如下:

    游戏简化为仅有一局;

    每位牌手有三行,分别是近战、远程和攻城;

    每位牌手每次按顺序出一张牌;

    每位牌手有同样数量张牌,而聪明的你能预知对手每次出的牌!

    牌分为以下几种功能:

    • 单位牌:有一个点数和放置位置,(0)(1)(2)分别表示近战、远程和攻城,放置在你的场上;
    • 天气牌:有一个影响位置(0)(1)(2)分别表示近战、远程和攻城, 对你的和对手的相应行都会影响。天气下的单位无法被烧灼(烧灼下面有解释),天气下的单位计算点数和的时候视为每个为(1),对已经有天气牌的行使用视作无效;
    • 反天气牌:去除所有的天气牌并去除天气牌的视为每个为(1)效果(当然也包括其他效果);
    • 烧灼牌:消灭全场现有战力最高的单位(包括自己的单位)(除了天气下的), 若有多个则都消灭,若没有单位则视为无效,后续放入同行的单位仍然视作被天气影响;
    • 号角牌:选择(6)行(包括对手的)中一行使该行现有单位战力翻倍,但不能对天气牌影响下的行使用。如果每行都有天气视作无效,否则必须选择一行。由于丢了一些牌,这种卡最多只会出现 2 张,而且只有你有。这种牌视为立刻生效,然后消失;

    所有牌都必须使用,且除了单位牌其他牌都没有点数。视作无效的牌不影响整个出牌过程,打出它什么用都没有,但你还是打出了它。

    你想要让最后你的点数和减去对手的尽量大(不是绝对值!),该怎么办呢?

    输入输出格式

    输入格式

    第一行两个数(W,N)分别表示先后手和每人牌数,(W=0)表示你先手,(W=1)表示对手先。

    接下来依次(N)行表示对手每次出的牌:

    • (t=1),这是一张单位牌,接下来(x,y)分别表示战力和位置;
    • (t=2),这是一张天气牌,接下来(x)表示位置;
    • (t=3),这是一张反天气牌;
    • (t=4),这是一张烧灼牌;
    • (t=5),这是一张号角牌。

    接下来(N)行表示你的牌,描述同上。

    输出格式

    点数和差的最大值和点数和差最大方案数,用空格分隔。

    号角放在不同行算不同方案(无效不算放在一行,但也是一种方案,同 012 行不同),且每张牌是不同的

    例如你有两种方案:第一张号角放在你的 1 行第二张号角放在你的 0 行与第一张号角放在你的 0 行第二张号角放在你的 1 行不同。

    数据范围

    对于(10\%)的数据,(tin{1})

    对于(20\%)的数据,(tin{1,2})

    对于(40\%)的数据,(tin{1,2,3})

    对于(60\%)的数据,(tin{1,2,3,4})

    对于(100\%)的数据,(Nle 7,1le)所有单位战力(le 1000)

    TIPS

    好好读题!

    好好读题!

    好好读题!


    要是联赛来这么一道大模拟我就飞了(flag

    首先读错题了,以为自己出牌的顺序也是给定好了。其次回溯时没想好怎么存原来的状态瞎搞了。

    以后做这种题一定要先想好,把题目读清楚,把大致思路理清楚,对怎么写大致有个结构认识再动笔

    也算是提醒了我自己,搜索时的状态如果理不太清楚直接开另外一个东西把状态存下来,待会再还回去。反正系统栈不差你这点东西。


    思路(流程):

    1. ( t{next\_permutation()})直接搞自己出牌的全排列
    2. 搜索自己和敌方出牌
      • ( t{vector})存每个人每一行的战斗力
      • 加人时( t{tmp})存一下一行的,搜完了还回去
      • 天气一样,存一下
      • 砍最大值可以先存下来,然后( t{sort})先找到,再去删掉

    学习了一些有关( t{vector})的姿势

    vector <int> a;
    a.pop_back();
    a.front();
    a.back();
    

    Code:

    #include <cstdio>
    #include <vector>
    #include <algorithm>
    std::vector <int > dw[2][3];
    struct node
    {
        int id,op,x,y;
        bool friend operator <(node n1,node n2){return n1.id<n2.id;}
    }opt[2][10];
    int weather[3],n,w;
    int cal()
    {
        int c[2]={0,0};
        for(int i=0;i<=2;i++)
            for(int k=0;k<=1;k++)
            {
                if(weather[i])
                    c[k]+=dw[k][i].size();
                else
                    for(int p=0;p<dw[k][i].size();p++)
                        c[k]+=dw[k][i][p];
            }
        return c[0]-c[1];
    }
    int max(int x,int y){return x>y?x:y;}
    int mxa=-0x3f3f3f3f,ans;
    void dfs(int who,int dep)
    {
        if(dep==n+1)
        {
            int d=cal();
            if(mxa<d) mxa=d,ans=1;
            else if(mxa==d) ++ans;
            return;
        }
        if(opt[who][dep].op==1)
        {
            int x=opt[who][dep].x,y=opt[who][dep].y;
            std::vector <int > tmp=dw[who][y];
            dw[who][y].push_back(x);
            dfs(who^1,dep+(who!=w));
            dw[who][y]=tmp;
        }
        else if(opt[who][dep].op==2)
        {
            int x=opt[who][dep].x;
            int tmp=weather[x];
            weather[x]=1;
            dfs(who^1,dep+(who!=w));
            weather[x]=tmp;
        }
        else if(opt[who][dep].op==3)
        {
            int tmp[3];
            for(int i=0;i<=2;i++) tmp[i]=weather[i],weather[i]=0;
            dfs(who^1,dep+(who!=w));
            for(int i=0;i<=2;i++) weather[i]=tmp[i];
        }
        else if(opt[who][dep].op==4)
        {
            int mx=0;
            std::vector <int> tmp[2][3];
            for(int i=0;i<=2;i++)
            {
                if(!weather[i])
                {
                    for(int k=0;k<=1;k++)
                    {
                        tmp[k][i]=dw[k][i];
                        std::sort(dw[k][i].begin(),dw[k][i].end());
                        if(!dw[k][i].empty()) mx=max(mx,dw[k][i].back());
                    }
                }
            }
            for(int i=0;i<=2;i++)
                if(!weather[i])
                    for(int k=0;k<=1;k++)
                        while(!dw[k][i].empty()&&dw[k][i].back()==mx) dw[k][i].pop_back();
            dfs(who^1,dep+(who!=w));
            for(int i=0;i<=2;i++)
                if(!weather[i])
                    for(int k=0;k<=1;k++)
                        dw[k][i]=tmp[k][i];
        }
        else
        {
            for(int i=0;i<=2;i++)
            {
                if(!weather[i])
                    for(int k=0;k<=1;k++)
                    {
                        for(int p=0;p<dw[k][i].size();p++)
                            dw[k][i][p]*=2;
                        dfs(who^1,dep+(who!=w));
                        for(int p=0;p<dw[k][i].size();p++)
                            dw[k][i][p]/=2;
                    }
            }
            if(weather[0]&weather[1]&weather[2]) dfs(who^1,dep+(who!=w));
        }
    }
    int main()
    {
        scanf("%d%d",&w,&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&opt[1][i].op);
            if(opt[1][i].op==1)
                scanf("%d%d",&opt[1][i].x,&opt[1][i].y);
            if(opt[1][i].op==2)
                scanf("%d",&opt[1][i].x);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&opt[0][i].op);
            if(opt[0][i].op==1)
                scanf("%d%d",&opt[0][i].x,&opt[0][i].y);
            if(opt[0][i].op==2)
                scanf("%d",&opt[0][i].x);
            opt[0][i].id=i;
        }
        dfs(w,1);
        while(std::next_permutation(opt[0]+1,opt[0]+1+n))
            dfs(w,1);
        printf("%d %d
    ",mxa,ans);
        return 0;
    }
    

    2018.11.6

  • 相关阅读:
    以&quot;小刀会“的成败论当今创业成败
    COCOS2D 学习笔记
    password加密的算法
    bzoj1087【SCOI2005】互不侵犯King
    HDU--2222--Keywords Search--AC自己主动机
    【leetcode】Subsets II (middle) ☆
    【leetcode】Word Search (middle)
    【hadoop2.6.0】利用JAVA API 实现数据上传
    【leetcode】Palindrome Partitioning II(hard) ☆
    【hadoop2.6.0】利用Hadoop的 Java API
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9915103.html
Copyright © 2020-2023  润新知