大致題意
原題鏈接
翻譯
\(有n個邏輯變量 請你分別對它們賦值 使其滿足m個命題\)
\(命題有四種格式:\)
-
單獨數字x 表示第x個邏輯變量為真
-
! + 數字x 表示第x個邏輯變量為假
-
若干個數字\(a_1, a_2, ..., a_p\)(不給出個數) -> 數字x 表示前面的a變量全為真
的時候x必定為真 -
若干個數字\(a_1, a_2, ..., a_p\)(不給出個數) -> ! + 數字x 表示前面的a變量全為真
的時候x必定為假
其中每個命題之間空行 即'\n'
注: 此題含有SPJ 可能有多種方案 任意輸出一種
思路
明顯的構造吧
考慮對於1,2類的命題 直接給變量賦值
對3,4類的命題 可以發現一個性質
即當a數組其中任意一個或多個邏輯變量值為0時 命題必定成立
為了方便構造 盡量滿足 我們盡量將此類條件按上述性質處理 即讓a數組有0
那么我們只需要將全部邏輯變量初值賦值為0(false)即可
在推出一個true變量后去更新其他變量 若a數組的值全部固定不為0 則后面的x的值也固定了
注意
這題的讀入有些毒瘤
例如
這個時候我們可以無視掉'->'因為你判斷數的個數就可以推出是1,2類命題還是3,4類命題
運用快讀的方法讀入數字 如下:
if (isdigit(ch))
isnum = true,
x = (x << 1) + (x << 3) + (ch ^ 48);
當ch(讀入字符)為'!'的時候 根據命題的性質 最多有一個!所以直接用bool記錄一下
if(ch == '!') sign = 1;
總的讀入如下
void rad(int x = 0, char ch = getchar(), bool isnum = false) {
Num.clear(); int sign = 0;
for (; ch != '\n' && ch != '\r' && ch != EOF; ch = getchar()) {
if (isdigit(ch))
isnum = true,
x = (x << 1) + (x << 3) + (ch ^ 48);
else {
if (isnum) Num.push_back(x);
x = isnum = 0; if(ch == '!') sign = 1;
}
}
if (isnum) Num.push_back(x);
if (Num.size() == 1) q.push(sign ? -Num[0] : Num[0]);
else {
deg[++ tot] = Num.size() - 1;
for (auto v : Num) e[v].push_back(tot);
to[tot] = sign? -Num[deg[tot]] : Num[deg[tot]];
}
}
實現
#include <bits/stdc++.h>
using namespace std;
int read(int x = 0, bool f = false, char ch = getchar()) {
for (; !isdigit(ch); ch = getchar()) f ^= (ch == '-');
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return f ? ~x + 1 : x;
}
const int N = 1e6 + 5;
int m, n, tot;
int dat[N], deg[N], to[N];
queue<int> q;
vector<int> Num, e[N];
void rad(int x = 0, char ch = getchar(), bool isnum = false) {
Num.clear(); int sign = 0;
for (; ch != '\n' && ch != '\r' && ch != EOF; ch = getchar()) {
if (isdigit(ch))
isnum = true,
x = (x << 1) + (x << 3) + (ch ^ 48);
else {
if (isnum) Num.push_back(x);
x = isnum = 0; if(ch == '!') sign = 1;
}
}
if (isnum) Num.push_back(x);
if (Num.size() == 1) q.push(sign ? -Num[0] : Num[0]);
else {
deg[++ tot] = Num.size() - 1;
for (auto v : Num) e[v].push_back(tot);
to[tot] = sign? -Num[deg[tot]] : Num[deg[tot]];
}
}
signed main() {
m = read(), n = read();
for (int i = 1; i <= m; ++i) rad();
while(q.size()) {
int x = q.front(); q.pop();
if (x < 0) {
x = -x;
if (dat[x] > 0) return puts("conflict"), 0;
dat[x] = -1;
} else {
if (dat[x] < 0) return puts("conflict"), 0;
if (dat[x]) continue; dat[x] = 1;
for (auto v : e[x]) {
if (!(--deg[v])) q.push(to[v]);
}
}
} for (int i = 1; i <= n; ++i) putchar(dat[i] == 1? 'T' : 'F');
return 0;
}
如果喜歡的話 點個贊再走吧