mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-10-28 02:52:41 +00:00
feat: 添加三值逻辑问题解决方案及测试代码
实现P9869问题的解决方案,包含主逻辑处理文件和测试文件。主文件处理三值逻辑(T/F/U)的变量赋值和关系操作,测试文件提供更详细的实现和注释。添加路径压缩和环检测机制来正确处理逻辑依赖关系。
This commit is contained in:
parent
5df5ae14a2
commit
413d070dbb
76
src/10/25/P9869.cpp
Normal file
76
src/10/25/P9869.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
using ll = int64_t;
|
||||
|
||||
const ll maxn = 1e5+5;
|
||||
const ll T=1e5+3,F=-1e5-3,U=0;
|
||||
ll c,t,n,m,f[maxn];
|
||||
std::bitset<2*maxn> vis;
|
||||
#define vis(x)vis[(x)+n]
|
||||
|
||||
static inline ll find(ll x){
|
||||
ll ret;
|
||||
if(x==T||x==F)ret=x;
|
||||
else if(vis(-x)||x==U){
|
||||
ret=U;
|
||||
}else if(vis(x))ret=T;
|
||||
else if(x<0){
|
||||
if(-f[-x] == x)ret=x;
|
||||
else{
|
||||
vis(x)=true;
|
||||
f[-x]=ret=find(-f[-x]);
|
||||
vis(x)=false;
|
||||
}
|
||||
}else{
|
||||
if(f[x]==x)ret=x;
|
||||
else{
|
||||
vis(x)=true;
|
||||
f[x]=ret=find(f[x]);
|
||||
vis(x)=false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void solve(){
|
||||
vis.reset();
|
||||
std::cin>>n>>m;
|
||||
ll ans=0;
|
||||
for(ll i=1;i<=n;i++)f[i]=i;
|
||||
for(ll i=1;i<=m;i++){
|
||||
char c;
|
||||
std::cin>>c;
|
||||
if(c=='T' || c=='F' || c=='U'){
|
||||
ll v;
|
||||
std::cin>>v;
|
||||
switch (c) {
|
||||
case 'T':f[v]=T;break;
|
||||
case 'F':f[v]=F;break;
|
||||
case 'U':f[v]=U;break;
|
||||
}
|
||||
}else if(c=='+'){
|
||||
ll i,j;
|
||||
std::cin>>i>>j;
|
||||
f[i]=f[j];
|
||||
}else if(c=='-'){
|
||||
ll i,j;
|
||||
std::cin>>i>>j;
|
||||
f[i]=-f[j];
|
||||
}
|
||||
}
|
||||
for(ll i=1;i<=n;i++){
|
||||
ans+=find(i)==U;
|
||||
}
|
||||
std::cout<<ans<<"\n";
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::iostream::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::cin>>c>>t;
|
||||
while (t--) {
|
||||
solve();
|
||||
}
|
||||
}
|
||||
97
src/10/25/P9869t.cpp
Normal file
97
src/10/25/P9869t.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include<bits/stdc++.h>
|
||||
#define int long long
|
||||
using namespace std;
|
||||
|
||||
// 定义三个特殊值来表示三值逻辑
|
||||
// 使用很大的数字来避免与普通变量下标冲突
|
||||
const int T = 100001, F = -100001, U = 0; // T代表True,F代表False,U代表Unknown
|
||||
|
||||
int c, t, n, m, a, b, fa[100005]; // fa数组用于记录每个变量的当前值或依赖关系
|
||||
char ch[100005]; // 存储每条语句的操作类型
|
||||
bool book[300005]; // 标记数组,用于在递归查找时检测环
|
||||
|
||||
// 核心函数:查找变量x的最终逻辑值
|
||||
int find(int x) {
|
||||
int re; // 返回值
|
||||
|
||||
// 情况1:如果x已经是基础值(T/F/U),直接返回
|
||||
if (x == T || x == F) re = x;
|
||||
else if (book[n - x] || x == U) re = U;
|
||||
// 这里book[n-x]是处理负数的标记,x==U表示已经是Unknown
|
||||
|
||||
// 情况2:如果x被标记为True(在递归路径中)
|
||||
else if (book[x + n]) re = T;
|
||||
|
||||
// 情况3:处理负数(表示逻辑非操作的结果)
|
||||
else if (x < 0) {
|
||||
// 如果负数指向自己,说明形成了自环,保持原值
|
||||
if (x == -fa[-x]) re = x;
|
||||
else {
|
||||
book[x + n] = 1; // 标记当前节点,防止无限递归
|
||||
// 递归查找:¬(¬A) = A,所以这里取双重否定
|
||||
re = find(-fa[-x]);
|
||||
book[x + n] = 0; // 回溯,清空标记
|
||||
}
|
||||
}
|
||||
|
||||
// 情况4:处理正数(普通变量引用)
|
||||
else {
|
||||
// 如果指向自己,说明是基础值或已确定的值
|
||||
if (x == fa[x]) re = x;
|
||||
else {
|
||||
book[x + n] = 1; // 标记当前节点
|
||||
// 递归查找依赖的值
|
||||
re = fa[x] = find(fa[x]); // 路径压缩
|
||||
book[x + n] = 0; // 回溯,清空标记
|
||||
}
|
||||
}
|
||||
return re;
|
||||
}
|
||||
|
||||
signed main() {
|
||||
cin >> c >> t; // 读入测试点编号和数据组数
|
||||
|
||||
while (t--) {
|
||||
cin >> n >> m; // 变量个数和语句条数
|
||||
|
||||
// 初始化:每个变量最初指向自己
|
||||
for (int i = 1; i <= n; i++) fa[i] = i;
|
||||
|
||||
// 处理每条语句
|
||||
for (int i = 1; i <= m; i++) {
|
||||
cin >> ch[i]; // 读入操作类型
|
||||
|
||||
if (ch[i] == 'T') { // 赋值为True
|
||||
cin >> a;
|
||||
fa[a] = T; // 直接标记为T
|
||||
}
|
||||
else if (ch[i] == 'F') { // 赋值为False
|
||||
cin >> a;
|
||||
fa[a] = F; // 直接标记为F
|
||||
}
|
||||
else if (ch[i] == 'U') { // 赋值为Unknown
|
||||
cin >> a;
|
||||
fa[a] = U; // 直接标记为U
|
||||
}
|
||||
else {
|
||||
cin >> a >> b;
|
||||
if (ch[i] == '+') { // 赋值操作:x_a ← x_b
|
||||
fa[a] = fa[b]; // 直接复制值或引用
|
||||
}
|
||||
else { // 取反操作:x_a ← ¬x_b
|
||||
fa[a] = -fa[b]; // 用负数表示逻辑非
|
||||
// 例如:如果fa[b]=T(100001),那么fa[a]=-100001
|
||||
// 这表示"非True",在find函数中会特殊处理
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ans = 0;
|
||||
// 统计最终值为Unknown的变量个数
|
||||
for (int i = 1; i <= n; i++) {
|
||||
if (find(i) == U) ans++;
|
||||
}
|
||||
cout << ans << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user