light oj 1261 - K-SAT Problem (模拟)

1261 - K-SAT Problem
Time Limit: 2 second(s)Memory Limit: 32 MB

SAT was the first known NP-complete problem. The problem remains NP-complete even if all expressions are written in conjunctive normal form with 3 variables per clause (3-CNF), yielding the 3-SAT problem. A K-SAT problem can be described as follows:

There are n persons, and m objects. Each person makes K wishes, for each of these wishes either he wants to take an object or he wants to reject an object. You have to take a subset of the objects such that every person is happy. A person is happy if at least one of his K wishes is kept. For example, there are 3 persons, 4 objects, and K = 2, and

Person 1 says, "take object 1 or reject 2."

Person 2 says, "take object 3 or 4."

Person 3 says, "reject object 3 or 1."

So, if we take object 1 2 3, then it is not a valid solution, since person 3 becomes unhappy. But if we take 1 2 4 then everyone becomes happy. If we take only 4, it's also a valid solution. Now you are given the information about the persons' wishes and the solution we are currently thinking. You have to say whether the solution is correct or not.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing three integers nmK (1 ≤ n, m, K ≤ 30). Each of the next n lines contains K space separated integers where the ithline denotes the wishes of the ith person. Each of the integers in a line will be either positive or negative. Positive means the person wants the object in the solution; negative means the person doesn't want that in the solution. You can assume that the absolute value of each of the integers will lie between 1 andm.

The next line contains an integer p (0 ≤ p ≤ m) denoting the number of integers in the solution, followed by p space separated integers each between 1and m, denoting the solution. That means the objects we have taken as solution set.

Output

For each case, print the case number and 'Yes' if the solution is valid or 'No' otherwise.

Sample Input

Output for Sample Input

2

3 4 2

+1 -2

+3 +4

-3 -1

1 4

1 5 3

+1 -2 +4

2 2 5

Case 1: Yes

Case 2: No

 

题意:n个人,每个人有k个愿望,正数代表希望这个数出现,负数不希望这个数出现,然后给出小于等于m的p个数,代表会出现的数,问最后能否满足每个人的至少一个愿望
思路:模拟。输出每个人的愿望,map[ ][ ]记录,set容器保存p个数,然后保存另外m-p个数的相反数
代码;
#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
int n,m,k,p;
set<int> st;
int map[40][40];
bool judge()//判断是否满足所有人的愿望
{
    int flag;
    int i,j;
    for(i=0;i<n;i++)
    {
        flag=0;
        for(j=0;j<k;j++)
        {
            if(st.count(map[i][j]))
            {
                flag=1;
                break;
            }
        }
        if(!flag)
            return false;
    }
    return true;
}
int main()
{
    int t,kcase=1,x;
    int vis[40];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        int i,j;
        for(i=0;i<n;i++)
        {
            for(j=0;j<k;j++)
                scanf("%d",&map[i][j]);
        }
        scanf("%d",&p);
        memset(vis,0,sizeof(vis));
        st.clear();
        for(i=0;i<p;i++)
        {
            scanf("%d",&x);
            st.insert(x);
            vis[x]=1;
        }
        for(i=1;i<=m;i++)
        {
            if(!vis[i])
                st.insert(-i);
        }
        if(judge())
            printf("Case %d: Yes\n",kcase++);
        else
            printf("Case %d: No\n",kcase++);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值