Compare commits

...

2 Commits

Author SHA1 Message Date
03f57b7619 feat: 添加P11454.cpp解题代码实现
实现了一个基于BFS的算法来解决P11454问题,包括输入处理、边界处理和结果计算。代码包含调试输出和性能优化措施。
2025-10-25 22:39:05 +08:00
413d070dbb feat: 添加三值逻辑问题解决方案及测试代码
实现P9869问题的解决方案,包含主逻辑处理文件和测试文件。主文件处理三值逻辑(T/F/U)的变量赋值和关系操作,测试文件提供更详细的实现和注释。添加路径压缩和环检测机制来正确处理逻辑依赖关系。
2025-10-25 20:24:35 +08:00
3 changed files with 261 additions and 0 deletions

88
src/10/25/P11454.cpp Normal file
View File

@ -0,0 +1,88 @@
#include <cstdint>
#include <cstdio>
#include <deque>
#include <iostream>
#include <istream>
#include <unordered_map>
using ll = int64_t;
const ll maxn=1007;
ll n,q,r[maxn],c[maxn];
char t[maxn];
enum Dir{
U='U',D='D',R='R',L='L'
};
char map[maxn][maxn];
bool vis[maxn][maxn];
const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
char idxokdir[4]={U,L,D,R};
int ans[int(2e5+7)];
#define printf
static inline ll bfs(ll x,ll y){
printf("bfs %lld,%lld\n",x,y);
ll res=0;
struct P{
ll x,y;
};
if(!vis[x][y])return 0;
std::deque<P> q;
q.emplace_back(x,y);
while (q.size()) {
auto[x,y]=q.front();
printf("get %lld %lld from q\n",x,y);
q.pop_front();
for(ll i=0;i<4;i++){
ll nx=x+dir[i][0],ny=y+dir[i][1];
if(nx<1||nx>n||ny<1||ny>n||vis[nx][ny]){
// printf("check %lld %lld not ok\n",nx,ny);
continue;
}
// printf("%lld %lld should be %c, but is %c\n",nx,ny,idxokdir[i],map[nx][ny]);
if(map[nx][ny]==idxokdir[i]||map[nx][ny]==0){
printf("ok %lld %lld\n",nx,ny);
q.emplace_back(nx,ny);
vis[nx][ny]=true;
res++;
}
}
}
printf("---out bfs\n");
return res;
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin>>n>>q;
for(ll i=1;i<=q;i++){
std::cin>>r[i]>>c[i]>>t[i];
map[r[i]][c[i]]=t[i];
}
ll firstans=0;
for(ll i=1;i<=n;i++){
vis[0][i]=1;
vis[n+1][i]=1;
vis[i][0]=1;
vis[i][n+1]=1;
firstans+=bfs(0, i);
firstans+=bfs(n+1,i);
firstans+=bfs(i,0);
firstans+=bfs(i, n+1);
}
ans[q]=n*n-firstans;
printf("START for loop\n");
for(ll i=q;i>=2;i--){
printf("FOR i=%lld\n",i);
map[r[i]][c[i]]=0;
for(ll j=0;j<4;j++){
firstans+=bfs(r[i]+dir[j][0], c[i]+dir[j][1]);
}
ans[i-1]=n*n-firstans;
}
for(ll i=1;i<=q;i++){
std::cout<<ans[i]<<"\n";
}
}

76
src/10/25/P9869.cpp Normal file
View 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
View 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代表TrueF代表FalseU代表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;
}