prow2012-A3-0018

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

zYc学长怎么没写题意啊???

题意:最正常的平胡麻将题(无十三幺,无七对糊法),问补上哪块牌可以胡。

模拟即可,加上某块牌后,用最暴力的DFS每次消去三块能连的,最后判断即可。



{{{


#include <iostream>
#include <vector>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
using namespace std;
int p[10],s[10],m[10],z[10],debug;
bool dfs(int a[],int limit,int lian){
    int i;
    for (i=1;i<10;i++)
        if (a[i]>0){
            if (a[i]>=3){
                a[i]-=3;
                if (dfs(a,limit,lian)) return true;
                a[i]+=3;
            }
            if (lian&&i+2<10&&a[i]>0&&a[i+1]>0&&a[i+2]>0)
            {
                a[i]--,a[i+1]--,a[i+2]--;
                if (dfs(a,limit,lian)) return true;
                a[i]++,a[i+1]++,a[i+2]++;
            }
        }
    int t = 0,dui=0;
    for (i=1;i<10;i++)
        if (a[i]>0)
        t+=a[i],dui++;
    //if (debug==28&&lian==0) printf("%d %d %d\n",limit,t,dui);
    if (limit==2&&t==2&&dui==1) return true;
    if (limit==0&&t==0) return true;
    return false;
}


bool find(int a[],int limit,int lian){
//  if (debug==28&&lian==0) printf("%d %d %d\n",limit,lian,z[0]);
    if (limit==1) return false;
    int b[10];
    for (int i=0;i<10;i++) {
        b[i] = a[i];

        if (i>0&&b[i]>4) return false;
    }
//  if (debug==28&&lian==0) printf("--------\n");
    bool res = dfs(a,limit,lian);
    for (int i=0;i<10;i++) a[i] = b[i];
    return res;
}
bool check(int i){
    int eye = 0;
    debug = i;
/*  if (i==28){
        for (int j=0;j<10;j++) 
            printf("%d ",z[j]);
        printf("\n");
    }*/
    if (!find(p,p[0]%3,1)) return false;
    if (p[0]%3==2) eye++;
//  if (i==28)printf("p\n");
    if (!find(s,s[0]%3,1)) return false;
    if (s[0]%3==2) eye++;
//  if (i==28)printf("s\n");
    if (!find(m,m[0]%3,1)) return false;
    if (m[0]%3==2) eye++;
//  if (i==28)printf("m\n");
    if (!find(z,z[0]%3,0)) return false;
    if (z[0]%3==2) eye++;
//  if (i==28) printf("%d\n",z[0]%3);
    if (eye==1) return true;
    return false;
}
int main(){
    char str[100];
    int i,j;
    int ans[100],res = 0;
    while(scanf("%s",str)!=EOF){
        memset(p,0,sizeof(p));
        memset(s,0,sizeof(s));
        memset(m,0,sizeof(m));
        memset(z,0,sizeof(z));
        for (i=0;i<26;i+=2){
            int c = str[i]-'0',d = str[i+1];
            if (d=='s')
                s[0]++,s[c]++;
            else if (d=='p')
                p[0]++,p[c]++;
            else if (d=='m')
                m[0]++,m[c]++;
            else if (d=='z')
                z[0]++,z[c]++;
        }
        res = 0;
        for (i=0;i<34;i++){
            if (i/9==0) m[0]++,m[i%9+1]++;
            else if (i/9==1) p[0]++,p[i%9+1]++;
            else if (i/9==2) s[0]++,s[i%9+1]++;
            else if (i/9==3) z[0]++,z[i%9+1]++;
            if (check(i)){
                ans[res++] = i;
            }
            if (i/9==0) m[0]--,m[i%9+1]--;
            else if (i/9==1) p[0]--,p[i%9+1]--;
            else if (i/9==2) s[0]--,s[i%9+1]--;
            else if (i/9==3) z[0]--,z[i%9+1]--;
        }
        if (res==0) printf("0");
            else 
            printf("%d ",res);
        char ch;
        for (j=0;j<res;j++){
            i = ans[j];
            if (i/9==0) ch = 'm';
            else if (i/9==1) ch='p';
            else if (i/9==2) ch = 's';
            else if (i/9==3) ch = 'z';
            printf("%d%c",i%9+1,ch);
        }
        printf("\n");
    }
}



}}}

zYc学长怎么没写题意啊???

题意:最正常的平胡麻将题(无十三幺,无七对糊法),问补上哪块牌可以胡。

模拟即可,加上某块牌后,用最暴力的DFS每次消去三块能连的,最后判断即可。

#include <iostream>
#include <vector>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
using namespace std;
int p[10],s[10],m[10],z[10],debug;
bool dfs(int a[],int limit,int lian){
    int i;
    for (i=1;i<10;i++)
        if (a[i]>0){
            if (a[i]>=3){
                a[i]-=3;
                if (dfs(a,limit,lian)) return true;
                a[i]+=3;
            }
            if (lian&&i+2<10&&a[i]>0&&a[i+1]>0&&a[i+2]>0)
            {
                a[i]--,a[i+1]--,a[i+2]--;
                if (dfs(a,limit,lian)) return true;
                a[i]++,a[i+1]++,a[i+2]++;
            }
        }
    int t = 0,dui=0;
    for (i=1;i<10;i++)
        if (a[i]>0)
        t+=a[i],dui++;
    //if (debug==28&&lian==0) printf("%d %d %d\n",limit,t,dui);
    if (limit==2&&t==2&&dui==1) return true;
    if (limit==0&&t==0) return true;
    return false;
}
bool find(int a[],int limit,int lian){
//  if (debug==28&&lian==0) printf("%d %d %d\n",limit,lian,z[0]);
    if (limit==1) return false;
    int b[10];
    for (int i=0;i<10;i++) {
        b[i] = a[i];
        if (i>0&&b[i]>4) return false;
    }
//  if (debug==28&&lian==0) printf("--------\n");
    bool res = dfs(a,limit,lian);
    for (int i=0;i<10;i++) a[i] = b[i];
    return res;
}
bool check(int i){
    int eye = 0;
    debug = i;
/*  if (i==28){
        for (int j=0;j<10;j++) 
            printf("%d ",z[j]);
        printf("\n");
    }*/
    if (!find(p,p[0]%3,1)) return false;
    if (p[0]%3==2) eye++;
//  if (i==28)printf("p\n");
    if (!find(s,s[0]%3,1)) return false;
    if (s[0]%3==2) eye++;
//  if (i==28)printf("s\n");
    if (!find(m,m[0]%3,1)) return false;
    if (m[0]%3==2) eye++;
//  if (i==28)printf("m\n");
    if (!find(z,z[0]%3,0)) return false;
    if (z[0]%3==2) eye++;
//  if (i==28) printf("%d\n",z[0]%3);
    if (eye==1) return true;
    return false;
}
int main(){
    char str[100];
    int i,j;
    int ans[100],res = 0;
    while(scanf("%s",str)!=EOF){
        memset(p,0,sizeof(p));
        memset(s,0,sizeof(s));
        memset(m,0,sizeof(m));
        memset(z,0,sizeof(z));
        for (i=0;i<26;i+=2){
            int c = str[i]-'0',d = str[i+1];
            if (d=='s')
                s[0]++,s[c]++;
            else if (d=='p')
                p[0]++,p[c]++;
            else if (d=='m')
                m[0]++,m[c]++;
            else if (d=='z')
                z[0]++,z[c]++;
        }
        res = 0;
        for (i=0;i<34;i++){
            if (i/9==0) m[0]++,m[i%9+1]++;
            else if (i/9==1) p[0]++,p[i%9+1]++;
            else if (i/9==2) s[0]++,s[i%9+1]++;
            else if (i/9==3) z[0]++,z[i%9+1]++;
            if (check(i)){
                ans[res++] = i;
            }
            if (i/9==0) m[0]--,m[i%9+1]--;
            else if (i/9==1) p[0]--,p[i%9+1]--;
            else if (i/9==2) s[0]--,s[i%9+1]--;
            else if (i/9==3) z[0]--,z[i%9+1]--;
        }
        if (res==0) printf("0");
            else 
            printf("%d ",res);
        char ch;
        for (j=0;j<res;j++){
            i = ans[j];
            if (i/9==0) ch = 'm';
            else if (i/9==1) ch='p';
            else if (i/9==2) ch = 's';
            else if (i/9==3) ch = 'z';
            printf("%d%c",i%9+1,ch);
        }
        printf("\n");
    }
}