HDOJ6269解题报告

题目地址:

  http://acm.hdu.edu.cn/showproblem.php?pid=4449

题目概述:

  2018CCPC杭州的重现赛,pdf见6264。

  题目大意是打炉石,不过细节挺多的,建议直接阅读原题。

大致思路:

  我们发现最多只有8张手牌还没有手牌补充,那么显然直接暴力模拟即可。

复杂度分析:

  O(n!)显然啦。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <ctime>
#include <map>
#include <assert.h>
#include <stack>
#include <set>
#include <bitset>
#include <queue>
#include <iomanip>
#include <cstring>
#include <algorithm>
using namespace std;

#define sacnf scanf
#define scnaf scanf
#define scnafi scanfi
#define pb push_back
#define Len size()
#define gchar getchar()
#define FOR(i,j,k) for(int (i)=(j);(i)<=(k);++(i))
#define mes(a,b) memset((a),(b),sizeof(a))
#define scanfi(a) scanf("%d",&(a))
#define scanfti(a,b) scanf("%d%d",&(a),&(b))
#define println(a) printf("%d\n",(a))
#define printIs(a) printf((a)?"ssi\n":"san\n")
#define print_b printf("\n")
#define IsNum(x) ('0'<=(x)&&(x)<='9')
#define lt dir*2
#define rt dir*2+1

#define maxn 300010
#define maxm 3000010
#define inf 1061109567
//const long long inf=1e15;
#define INF 0x3f3f3f3f
#define eps 1e-8
#define E 2.718281828459
const double PI=acos(-1.0);
//#define mod 1000
const long long mod=1000000007;
#define MAXNUM 1000000000

typedef long long ll;
typedef unsigned long long ulld;
ll Abs(ll x) {return (x<0)?-x:x;}
int Read() {char ch;int res=0;while(ch=getchar(),!(IsNum(ch)));while(IsNum(ch)) res=res*10+ch-'0',ch=getchar();return res;}

struct card
{
    int cost;
    int damage,extra_dmg;
    int type;
} crd[10];

int order[10];

int n,Hm,He,used_card,used_rnd;
int atk[5],cur[5],hel[5];

int target[10],rnd;

bool dfs(int pos,int extra,int rnd,int spell,int myH,int othH,int c1,int c2,int c3)
{
    if(myH>0&&othH<=0)
    {
        used_card=pos-1;used_rnd=rnd;return true;
    }
    if(pos>n) return false;int id=order[pos];
    if(spell<crd[id].cost)
    {
        int total=0;
        total+=atk[1]*(c1>0);c1=hel[1];
        total+=atk[2]*(c2>0);c2=hel[2];
        total+=atk[3]*(c3>0);c3=hel[3];
        extra=0;myH-=total;rnd++;spell=10;
    }
    if(myH<=0||rnd>3) return false;
    if(crd[id].type==3)
    {
        if(c1>0)
        {
            target[pos]=1;
            if(dfs(pos+1,extra,rnd,spell-crd[id].cost,myH,othH,c1-crd[id].damage-extra,c2,c3))
                return true;
            target[pos]=-1;
        }

        if(c2>0)
        {
            target[pos]=2;
            if(dfs(pos+1,extra,rnd,spell-crd[id].cost,myH,othH,c1,c2-crd[id].damage-extra,c3))
                return true;
            target[pos]=-1;
        }

        if(c3>0)
        {
            target[pos]=3;
            if(dfs(pos+1,extra,rnd,spell-crd[id].cost,myH,othH,c1,c2,c3-crd[id].damage-extra))
                return true;
            target[pos]=-1;
        }

        target[pos]=0;
        if(dfs(pos+1,extra,rnd,spell-crd[id].cost,myH,othH-crd[id].damage-extra,c1,c2,c3)) return true;
        target[pos]=-1;
    }
    else if(crd[id].type==2)
    {
        target[pos]=0;
        if(dfs(pos+1,extra+crd[id].extra_dmg,rnd,spell-crd[id].cost,myH,othH-crd[id].damage-extra,c1,c2,c3))
            return true;
        target[pos]=-1;
    }
    else
    {
        if(dfs(pos+1,extra+crd[id].extra_dmg,rnd,spell-crd[id].cost,myH,othH,
               c1-crd[id].damage-extra,c2-crd[id].damage-extra,c3-crd[id].damage-extra)) return true;
    }
    return false;
}

int main()
{
    //freopen("data.in","r",stdin);
    //freopen("std.out","w",stdout);
    //clock_t st=clock();
    int T;scanfi(T);
    while(T--)
    {
        scanfi(n);
        scanfti(Hm,He);
        FOR(i,1,3) scanf("%d%d%d",&atk[i],&cur[i],&hel[i]);
        FOR(i,1,n)
        {
            scanfti(crd[i].type,crd[i].cost);
            if(crd[i].type==3)
            {
                scanfi(crd[i].damage);
                crd[i].extra_dmg=0;
            }
            else scanfti(crd[i].damage,crd[i].extra_dmg);
            order[i]=i;
        }
        bool win=false;
        do
        {
            used_card=0;used_rnd=1;
            if(dfs(1,0,1,10,Hm,He,cur[1],cur[2],cur[3])) {win=true;break;}
        } while(next_permutation(order+1,order+n+1));
        if(!win) {printf("No\n");continue;}
        printf("Yes\n");int j=1;
        for(int i=1;i<=3;i++)
        {
            int spell=0;
            if(i<=used_rnd)
            {
                int lk=j;
                spell+=crd[order[j]].cost;j++;
                while(j<=used_card&&spell+crd[order[j]].cost<=10)
                {
                    spell+=crd[order[j]].cost;j++;
                }
                printf("%d\n",j-lk);
                for(int k=lk;k<j-1;k++) printf("%d ",order[k]);
                printf("%d\n%d",order[j-1],crd[order[lk]].type==3?target[lk]:-1);
                for(int k=lk+1;k<j;k++)
                {
                    int nowTarget=crd[order[k]].type==3?target[k]:-1;
                    printf(" %d",nowTarget);
                }
                print_b;
            }
            else printf("0\n");
        }
    }
    //clock_t ed=clock();
    //printf("\nTIme Used: %f Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
    return 0;
}
//

 

posted @ 2018-04-15 11:40  CtrlKismet  阅读(223)  评论(0编辑  收藏  举报