hit or miss 解题报告

hit or miss 解题报告
方法一:

#include<iostream>
using namespace std;
const int maxn=10010;
const int maxm=15;
int i,j,k,m,n;
int sum;
int head[maxm],tail[maxm],counter[maxm];
int f[maxm][maxn];

int check(int cn)
{
    int ci;
    for(ci=1;ci<cn;++ci)if(tail[ci]>=head[ci])return 0;
    int ck;
    ck=counter[cn];
    for(ci=head[cn];ci<=tail[cn];++ci)
    {
        ++ck;
        if(ck==14)ck=1;
        if(f[cn][ci]==ck)return 0;
    }
    sum=-1;
    return 0;
}
int main()
{
    cin>>n;
    int ni;
    for(ni=1;ni<=n;++ni)
    {
        cin>>m;
        for(i=1;i<=52;++i) cin>>f[1][i];
        for(i=1;i<=m;++i)
        {
            counter[i]=0;
            head[i]=1;
            tail[i]=0;
        }
        tail[1]=52;
        sum=52;
        check(1);
        while(sum>0)
        {
            for(i=1;i<=m;++i)
            {
                //            cout<<i<<":"<<tail[i]-head[i]+1<<endl;
                if(sum<=0)break;
                if(head[i]>tail[i]) continue;
                ++counter[i];
                if(counter[i]==14)counter[i]=1;

                if(f[i][head[i]]!=counter[i])
                {
                    ++tail[i];
                    f[i][tail[i]]=f[i][head[i]];
                    ++head[i];
                    continue;
                }
                if(i==m)
                {
                    --sum;
                    ++head[i];
                    if((tail[i]-head[i]+1>0)&&((tail[i]-head[i]+1)%13==0))check(i);
                    continue;
                }
                j=i+1;
                ++tail[j];
                f[j][tail[j]]=f[i][head[i]];
                if((tail[j]-head[j]+1>0)&&((tail[j]-head[j]+1)%13==0))check(j);
                ++head[i];
                if((tail[i]-head[i]+1>0)&&((tail[i]-head[i]+1)%13==0))check(i);
            }
        }
        if(sum==-1)
        {
            cout<<"Case "<<ni<<": unwinnable"<<endl;
            continue;
        }
        cout<<"Case "<<ni<<":";
        for(i=1;i<=m;++i)cout<<" "<<f[i][tail[i]];
        cout<<endl;
    }
    return 0;
}
//这个判定条件比较难以理解,但这种用数组简明的模拟队列在效率上会有很大的提高,而且该代码在逻辑上非常明确在许多分支的判定语句上都做了相应的化简。

方法二:

#include <iostream>
#include <queue>
using namespace std;
int const per_max = 22;
int ans[per_max]={0};

int main() {
    int t;
    cin>>t;

    for (int id = 1;id<=t;id++) {
        int m;
        cin>>m;
        queue<int> person[22];   
        int tot[per_max] = {0};
        int count[per_max]={0};
        for (int i=0;i<52;i++) {
            int tmp;
            cin>>tmp;
            person[0].push(tmp);
        }

        int i = 0;
        int sum = 52;
        int win = 0;
        while(sum) {

                if (person[i].empty()) {
                    i++;
                    if (i==m) i=0;
                    continue;
                }
                tot[i]++;   
                count[i]++;
                if(count[i]==14) count[i] = 1;
                if(count[i] ==  person[i].front()) {
                    ans[i] = person[i].front();

                    person[i+1].push(person[i].front());
                    tot[i]=0;
                    person[i].pop();
                    if (i==m-1)
                    sum--;

                } else {
                    person[i].push(person[i].front());
                    person[i].pop();
                }
                if(tot[i]>int(person[i].size()*13)) break;
                i++;
                if (i==m) i=0;
        }
       cout<<"Case " <<id<<": ";
        if (sum!=0) {
            cout<<"unwinnable";
        } else {
            for (int i=0;i<m-1;i++) cout<<ans[i]<<" ";
            cout<<ans[m-1];
        }
        cout<<endl;
    }
}
/*此方法容易直观,运用stl库的良好封装性,所以代码量较少,但可能本人水平有限一直不知道怎么在调试过程中查看stl数据类型中相应的值的量。此题的判定终止条件是队列的长度乘以13对应了极限的情况即每位数均与1-13个数比较,较方法一更易于理解*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值