【题解】推理

题目描述

  有N(1 <= N <= 20)个杯子,从左往右排成一行,每个杯子要么有一枚硬币,要么没有硬币。
  现在有M (1 <= M<= 100)个询问,每个询问的是格式是:由N个0、1组成的序列,表示询问是1的那些杯子中  共有几个杯子是有硬币的?
  例如:1000,表示询问第一个杯子中有没有硬币?
  0110则表示询问第2、3两个杯子中有几个杯子有硬币?
  1001则表示询问第1、4两个杯子中有几个杯子有硬币?
  0011则表示第3、4两个杯子中有几个杯子有硬币?  
  现在你每询问一个问题,你都得到一个答案,当你问完M个问题后,你可以推导出这N个杯子的状态吗?
  也就是各个杯子是否有硬币?如果你得到的这M个回答有矛盾,输出IMPOSSIBLE,
  如果有多种可能则输出NOT UNIQUE,
  否则输出第1、2、..N个杯子的状态,0表示没硬币,1表示有硬币。

输入输出格式

输入格式

  第1行:N和M。
  第2..M+1行:先是一个01序列,表示询问,然后是你得到的答案。

输出格式

  NOT UNIQUE或者IMPOSSIBLE或者一行01序列。

输入输出样例

输入样例

4  5
1000  1
0110  1
1001  1
0011  1
0101  0

输出样例

1010 

题解

  用二进制的形式来记录杯子的拥有情况,每次枚举所有询问来判断即可。

#include <iostream>

#define MAX_N (20 + 5)
#define MAX_M (100 + 5) 
#define LIM ((1 << 20) + 5)

#define lowbit(x) ((x) & -(x))

using namespace std;

int n, m;
int a[MAX_M], c[MAX_M];
int p[LIM];
int lim;
int ans = -1;

void DFS(int now, int l)
{
    int tmp, nxt = now;
    int f = 1;
    for(register int i = 1; i <= m; ++i)
    {
        tmp = now & a[i];
        if(p[tmp] > c[i]) return;
        if(p[tmp] < c[i]) f = 0;
        nxt |= tmp;
    }
    if(f)
    {
        if(ans == -1) ans = now;
        else 
        {
            ans = -2;
            return;    
        }
    }
    nxt = ~nxt & lim;
    while(nxt)
    {
        if(lowbit(nxt) > l) DFS(now + lowbit(nxt), lowbit(nxt));;
        nxt -= lowbit(nxt);
    }
    return;
}

int main()
{
    cin >> n >> m;
    lim = (1 << n) - 1;
    char s[MAX_N]; 
    for(register int i = 1; i <= m; ++i)
    {
        cin >> s >> c[i];
        for(register int j = 0; j < n; ++j)
        {
            a[i] <<= 1;
            if(s[j] == '1') a[i] |= 1;
        }
    }
    int tmp;
    for(register int i = 0; i <= lim; ++i)
    {
        tmp = i;
        while(tmp)
        {
            ++p[i];
            tmp -= lowbit(tmp);
        }
    }
    DFS(0, 0);
    if(ans == -1) return cout << "IMPOSSIBLE", 0;
    if(ans == -2) return cout << "NOT UNIQUE", 0;
    s[n] = 0;
    for(register int i = n - 1; i >= 0; --i)
    {
        s[i] = (ans & 1) + '0';
        ans >>= 1;
    }
    cout << s;
    return 0;
}
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10682923.html