【留坑】UVA246 模拟题,STL容器组合_deque&&(set判重 OR hash判重)

1 题意。

2 分析

STL用降低性能换来更强的兼容/方便,当需要判重的type比较复杂时可以考虑用set,set.insert(),然后用set.find(),写起来方便一些。如本题,向lab104_yifan学习,代码一用set方便很多。

代码二依然用的hash。。没调出来,实在不想调了,先放这记录一下,以后有空再看。。

3

代码一

#include <iostream>
#include <string.h>
#include <algorithm>
#include <set>  //set have insert,not have push_back
#include <deque>
#include <vector>
#include <stdio.h>
using namespace std;

vector<deque<int> >pile;
set<vector<deque<int> > > vis;
int cur=0,pos=0;
void Ini(int num){
    cur=pos=0;
    pile.clear();
    vis.clear();
    for(int i=0;i<8;i++){
        pile.push_back(deque<int>());
    }
    pile[0].push_back(num);
    cur++;
    for(int i=1;i<7;i++){
        scanf("%d",&num);
        pile[i%7].push_back(num);
        cur++;
    }
    for(int i=7;i<52;i++){
        scanf("%d",&num);
        pile[7].push_back(num);
    }
    vis.insert(pile);
}
int Judge(int pos){
    int len=pile[pos].size();
    if(len<3)   return 0;
    int num1=pile[pos][0]+pile[pos][1]+pile[pos][len-1];
    int num2=pile[pos][0]+pile[pos][len-2]+pile[pos][len-1];
    int num3=pile[pos][len-3]+pile[pos][len-2]+pile[pos][len-1];
    if(num1==10||num1==20||num1==30)
        return 1;
    else if(num2==10||num2==20||num2==30)
        return 2;
    else if(num3==10||num3==20||num3==30)
        return 3;
    return 0;
}
int Empty(){
    for(int i=0;i<7;i++)
        if(pile[i].size()!=0)
            return 0;
    return 1;
}
int Draw(){
    if(vis.find(pile)!=vis.end())
        return 1;
    return 0;
}
int Fun(){
    pos=0;
    while(!pile[7].empty()){
        int card=pile[7].front();
        pile[7].pop_front();
        pile[pos].push_back(card);
        cur++;
        int judge=Judge(pos);
        while(judge!=0){//将pos消失的牌抽回手中
            int len=pile[pos].size();
            if(judge==1){
                pile[7].push_back(pile[pos][0]);
                pile[7].push_back(pile[pos][1]);
                pile[7].push_back(pile[pos][len-1]);
                pile[pos].pop_front();
                pile[pos].pop_front();
                pile[pos].pop_back();
            }
            else if(judge==2){
                pile[7].push_back(pile[pos][0]);
                pile[7].push_back(pile[pos][len-2]);
                pile[7].push_back(pile[pos][len-1]);
                pile[pos].pop_front();
                pile[pos].pop_back();
                pile[pos].pop_back();
            }
            else if(judge==3){
                pile[7].push_back(pile[pos][len-3]);
                pile[7].push_back(pile[pos][len-2]);
                pile[7].push_back(pile[pos][len-1]);
                pile[pos].pop_back();
                pile[pos].pop_back();
                pile[pos].pop_back();
            }
            judge=Judge(pos);
        }
        if(Empty()==1)
            return 1;//七堆牌均消失了。
        if(Draw()==1&&!pile[7].empty())
            return 3;//该状态出现过
        vis.insert(pile);
        pos=(++pos==7)?0:pos;
        while(pile[pos].empty()==1){//发牌跳过空堆
            pos=(++pos==7)?0:pos;
        }
    }
    return 2;//木有手牌了
}
int main()
{
    int num;
    while(~scanf("%d",&num)&&num!=0){
        Ini(num);
        int res=Fun();
        if(res==1)
            printf("Win : %d\n",cur);
        else if(res==2)
            printf("Loss: %d\n",cur);
        else if(res==3)
            printf("Draw: %d\n",cur);
    }
}


代码二

#include <iostream>
#include <stdio.h>
#include <deque>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;

typedef unsigned long long lll;
const int maxn=1200007;//Prime
const int mod=maxn;
deque<int> dqe;///  front 1 <- 2 <- 3 <- 4 back;
deque<int> pile[7];
int cur=1,res=0,coun=0;
struct Node{
    vector<int> cur_pile[8];//cur_pile[7] 是 当前手牌
    int next;
}hash_[maxn];
int hash_head[maxn];
int pile_all_zero(){
    for(int i=0;i<7;i++){
        if(pile[i].size()!=0){
            return 0;
        }
    }
    return 1;
}
void Prin(){
    for(int i=1;i<cur;i++){
        cout<<"cur: "<<cur<<endl;
        cout<<"pile:    "<<endl;
        for(int j=0;j<7;j++){
            cout<<"j: "<<j<<endl;
            for(int k=0;k<hash_[i].cur_pile[j].size();k++){
                cout<<hash_[i].cur_pile[j][k]<<" ";
            }
            cout<<endl;
        }
        cout<<"dqe: "<<endl;
        for(int j=0;j<hash_[i].cur_pile[7].size();j++){
            cout<<dqe[j]<<" ";
        }
        cout<<endl;
    }
    cout<<"END."<<endl;
}
int Search(){
    int key=0;
    for(int i=0;i<7;i++){
        for(int j=0;j<pile[i].size();j++){
            key=(key*13+pile[i][j])%mod;
        }
    }
    for(int j=0;j<dqe.size();j++){
        key=(key*13+dqe[j])%mod;
    }
    int u=hash_head[key];
    while(u){
        int bj=1;
        for(int i=0;i<7;i++){
            if(hash_[u].cur_pile[i].size()!=pile[i].size()){
                bj=0;
                break;
            }
            for(int j=0;j<pile[i].size();j++){
                if(hash_[u].cur_pile[i][j]!=pile[i][j]){
                    bj=0;
                    break;
                }
            }
        }
        if(bj==1){
            if(hash_[u].cur_pile[7].size()!=dqe.size()){
                bj=0;
            }
            else{
                for(int j=0;j<dqe.size();j++){
                    if(hash_[u].cur_pile[7][j]!=dqe[j]){
                        bj=0;
                        break;
                    }
                }
            }
        }
        if(bj==1){
            return 1;
        }
        u=hash_[u].next;
    }
    return 0;
}
void Insert(){
    int key=0;
    for(int i=0;i<7;i++){
        for(int j=0;j<pile[i].size();j++){
            key=(key*13+pile[i][j])%mod;
        }
    }
    for(int j=0;j<dqe.size();j++){
        key=(key*13+dqe[j])%mod;
    }
    hash_[cur].next=hash_head[key];
    for(int i=0;i<7;i++){

        for(int j=0;j<pile[i].size();j++){
            hash_[cur].cur_pile[i].push_back(pile[i][j]);
        }
    }
    for(int j=0;j<dqe.size();j++)
        hash_[cur].cur_pile[7].push_back(dqe[j]);
    hash_head[key]=cur++;
}
int Do(){
    int len=pile[res].size();
    if(len<3)   return 0;
    int do1=pile[res][0]+pile[res][1]+pile[res][len-1];
    int do2=pile[res][0]+pile[res][len-2]+pile[res][len-1];
    int do3=pile[res][len-3]+pile[res][len-2]+pile[res][len-1];
    if(10==do1||20==do1||30==do1){
        dqe.push_back(pile[res][0]);///可以写个宏,方便输入
        dqe.push_back(pile[res][1]);
        dqe.push_back(pile[res][len-1]);
        pile[res].pop_front();
        pile[res].pop_front();
        pile[res].pop_back();
        return 1;
    }
    else if(10==do2||20==do2||30==do2){
        dqe.push_back(pile[res][0]);
        dqe.push_back(pile[res][len-2]);
        dqe.push_back(pile[res][len-1]);
        pile[res].pop_front();
        pile[res].pop_back();
        pile[res].pop_back();
        return 2;
    }
    else if(10==do3||20==do3||30==do3){
        dqe.push_back(pile[res][len-3]);
        dqe.push_back(pile[res][len-2]);
        dqe.push_back(pile[res][len-1]);
        pile[res].pop_back();
        pile[res].pop_back();
        pile[res].pop_back();
        return 3;
    }
    else{
        return 0;
    }
}
int Fun(){
    res=0;
    while(!dqe.empty()){
        pile[res].push_back(dqe.front());
        coun++;
        dqe.pop_front();
        int temp1=Do();

        while(temp1!=0){
            temp1=Do();
        }//抽三张牌到手牌

        if(1==pile_all_zero())  return 1;
        else  if(1==Search())     return 3;
        //else  if(dqe.empty())   return 2;

        Insert();

        res=(++res==7)?0:res;//res=(++res)%7;
        while(coun>=15&&1==pile[res].empty()){
            res=(++res==7)?0:res;
            //res=(++res)%7;
        }


    }
    return 2;
}
void Ini(){
    dqe.clear();
    for(int i=0;i<7;i++)
        pile[i].clear();
    for(int i=0;i<cur;i++){
        hash_head[i]=0;
    }
    coun=cur=1;
}
int main()
{
    //2 6 5 10 10 4 10 10 10 4 5 10 4 5 10 9 7 6 1 7 6 9 5 3 10 10 4 10 9 2 1 10 1 10 10 10 3 10 9 8 10 8 7 1 2 8 6 7 3 3 8 2
    //4 3 2 10 8 10 6 8 9 5 8 10 5 3 5 4 6 9 9 1 7 6 3 5 10 10 8 10 9 10 10 7 2 6 10 10 4 10 1 3 10 1 1 10 2 2 10 4 10 7 7 10
    //10 5 4 3 5 7 10 8 2 3 9 10 8 4 5 1 7 6 7 2 6 9 10 2 3 10 3 4 4 9 10 1 1 10   5 10 10 1 8 10 7 8 10 6 10 10 10 9 6 2 10 10

    //freopen("out.txt","w",stdout);

    int num1;
    while(~scanf("%d",&num1)&&num1!=0){///输入待会要改
        ///INI
        Ini();
        dqe.push_back(num1);

        for(int i=2;i<=52;i++){
            scanf("%d",&num1);
            //cout<<"i: "<<i<<"  num1:"<<num1<<endl;
            dqe.push_back(num1);
        }

        ///FUNCTION
        int bj=Fun();

        //Prin();测试输出函数

        if(1==bj)
            printf("Win : %d\n",coun);
        else if(2==bj)
            printf("Loss: %d\n",coun);
        else if(3==bj)
            printf("Draw: %d\n",coun);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值