枚举 hdu1172 猜数字

因为时间给的非常多,然后测试组数又很小,所以是一个很粗暴的模拟


只要从1000到9999枚举答案,然后再判断符合答案的个数,看个数的数量差不多就做完了

然后就在于如何判断有几个数字同时存在,我的思路是用vis1和vis2分别记录进行比较的两个数字中,每个数字出现的次数

那么如果对于某个数字,vis1[i]和vis2[i]都不等于0,就说明有min(vis1[i],vis2[i])个数字同时存在


还有把,,就是,,突然爱上宏定义了,,本来刚开始的时候写了一大堆的for,后来发现用For的写法,写起来真轻松!


#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<functional>
#include<algorithm>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 1000 + 5;
const int INF = 0x3f3f3f3f;
#define For(i,x,y) for(int i=x;i<=y;i++)
#define mem(x,y) memset(x,y,sizeof(x))
/***************************************/

int A[MX], B[MX], C[MX];
int vis1[100], vis2[100];

void get(int x, int w[]) {
    For(i, 0, 3) {
        w[i] = x % 10;
        x /= 10;
    }
}

bool check(int x, int n) {
    int a[4], s[4];
    get(x, a);

    For(i, 0, 3) vis1[a[i]]++;

    For(id, 1, n) {
        get(A[id], s);

        For(i, 0, 3) vis2[s[i]]++;

        int c1 = 0, c2 = 0;
        For(i, 0, 9) {
            if(vis1[i] && vis2[i]) {
                c1 += min(vis1[i], vis2[i]);
            }
        }

        For(i, 0, 3) c2 += (a[i] == s[i]);
        For(i, 0, 3) vis2[s[i]] = 0;

        if(B[id] != c1 || C[id] != c2) {
            For(i, 0, 3) vis1[a[i]] = 0;
            return false;
        }
    }
    For(i, 0, 3) vis1[a[i]] = 0;
    return true;
}

int main() {
    int n;
    while(~scanf("%d", &n), n) {
        mem(vis1, 0);
        mem(vis2, 0);

        For(i, 1, n) {
            scanf("%d%d%d", &A[i], &B[i], &C[i]);
        }

        int cnt = 0, ans;
        For(i, 1000, 9999) {
            if(check(i, n)) {
                cnt++;
                ans = i;
            }
        }

        if(cnt == 1) {
            printf("%d\n", ans);
        } else {
            printf("Not sure\n");
        }
    }
    return 0;
}


你可能感兴趣的:(枚举 hdu1172 猜数字)