比赛 NOIP模拟赛by mzx Day1 评测结果 WWWWWWWWWW
题目名称 昆特-冠位指定 最终得分 0
用户昵称 liu_runda 运行时间 0.830 s
代码语言 C++ 内存使用 6.01 MiB
提交时间 2016-10-19 21:39:56
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005;
int n,m,k;
//1:近战 2:远程 3:攻城 
bool weather[6]; //每一排是否有恶劣天气 
struct land{
    int sum[2][6],cnt[2][6],_sum[2][6],_cnt[2][6];//cnt:卡牌数 sum:力量和   [0][]:单位    [1][]:英雄   加下划线:对方间谍 
    bool haojiao[6];//号角影响对应牌己方单位和对方间谍单位 
}di,zx;
struct card{
    int v,typ1,typ2,typ3,li;//typ1 1:单位 2:特殊 3:英雄 
    void read(){
        scanf("%d",&v); 
        scanf("%d",&typ1);
        if(typ1!=2){
            scanf("%d%d%d",&li,&typ2,&typ3);
        }else{
            scanf("%d",&typ2);
        }
    }
    bool operator <(const card &B)const{
        return v<B.v;
    }
}cards[maxn],spy[maxn],buf[maxn];int tot1=0,tot2=0;//tot1:非间谍牌 tot2:间谍牌
int bisearch(int x){
    int l=1,r=tot1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(cards[mid].v<=x)l=mid+1;
        else r=mid-1;
    }
    return l-1;
}
bool cmp(const card &a,const card &b){
    return a.li>b.li;
}
int sumd=0;
bool check(int ans){
    land d=di,z=zx;//复制一份 
    //使用所有能使用的间谍牌
    int able=k;//最多还能拿几张牌 
    int sumz=0;
    for(int i=1;i<=tot2&&spy[i].v<=ans;++i){
         sumz+=spy[i].li;
         /*if(spy[i].typ1==1){
              d._cnt[0][spy[i].typ2]++;
              d._sum[0][spy[i].typ2]+=spy[i].li;
         }else{
              d._cnt[1][spy[i].typ2]++;
              d._sum[1][spy[i].typ2]+=spy[i].li;
         }*/
        able++;
    }
    int lim=bisearch(ans);
    if(able>lim){//可以全用 
        for(int i=1;i<=lim;++i){
            sumz+=cards[i].li;
            /*if(cards[i].typ1==1){
                z.cnt[0][cards[i].typ2]++;z.sum[0][cards[i].typ2]+=cards[i].li;
            }else if(cards[i].typ1==3){
                z.cnt[1][cards[i].typ2]++;z.sum[1][cards[i].typ2]+=cards[i].li;
            }*/
        }
    }
    else{
        memcpy(buf+1,cards+1,sizeof(card)*lim);
        sort(buf+1,buf+lim+1,cmp);
        for(int i=1;i<=able;++i){
            sumz+=buf[i].li;
            /*if(cards[i].typ1==1){
                z.cnt[0][cards[i].typ2]++;z.sum[0][cards[i].typ2]+=cards[i].li;
            }else if(cards[i].typ1==3){
                z.cnt[1][cards[i].typ2]++;z.sum[1][cards[i].typ2]+=cards[i].li;
            }*/ 
        }
    }
    //结算 
    return sumz>=sumd;
}
int main(){
    freopen("gwent_grandorder.in","r",stdin);
    freopen("gwent_grandorder.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    int typ,li,v,typ2,typ3; 
    bool flag=false;
    for(int i=1;i<=m;++i){
        scanf("%d%d",&v,&typ);//敌方牌的稀有度没有用
        if(typ==1){//敌方单位牌 
            scanf("%d%d%d",&li,&typ2,&typ3);
            /*if(typ3==0){//敌方正常单位 
                di.cnt[0][typ2]++;
                di.sum[0][typ2]+=li;
            }else{//敌方间谍单位
                zx._cnt[0][typ2]++;
                zx._sum[0][typ2]+=li; 
            }*/
            sumd+=li;
        }else if(typ==3){//敌方英雄牌
            scanf("%d%d%d",&li,&typ2,&typ3);
            //敌方正常英雄
            /*di.cnt[1][typ2]++;
            di.sum[1][typ2]+=li;*/
            sumd+=li;
            //敌方间谍英雄,不受天气牌影响,不受号角影响,和放在对方原来那一排没有任何区别 ,和正常英雄一样处理 
        }else{//特殊牌
             flag=true;
             scanf("%d",&typ2);
             if(typ2==5){//敌方天晴 
                  memset(weather,0,sizeof(weather));
             }else if(typ2==0){//敌方领导号角 
                  scanf("%d",&typ3); //1:近战 2:远程 3:攻城   
                  di.haojiao[typ3]=true;
             }else{//敌方恶劣天气 
                  if(typ2<=3){//1:近战 2:远程 3:攻城   
                       weather[typ2]=true;
                  }else{//4:远程和攻城
                       weather[2]=weather[3]=true;
                  }
             }
        }
    }
    card c;
    for(int i=1;i<=n;++i){
        c.read();
        if(c.typ1!=2&&c.typ3==1)spy[++tot2]=c;
        else cards[++tot1]=c;
    }
    sort(cards+1,cards+tot1+1);
    sort(spy+1,spy+tot2+1);
    if(flag||(!check(0x7f7f7f7f))){
        printf("SingleDogMZX\n");
        fclose(stdin);fclose(stdout);
        return 0;
    } 
    int l=cards[1].v,r=max(cards[tot1].v,spy[tot2].v);
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",r+1);
    fclose(stdin);fclose(stdout);
    return 0;
}
/*
2 1 1
1 1 10 1 0
1 1 10 1 0
0 1 10 1 0
*/