求助啊,快疯掉了(玄关)
  • 板块题目总版
  • 楼主linjinkun
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/9/21 22:59
  • 上次更新2024/9/22 08:25:36
查看原帖
求助啊,快疯掉了(玄关)
1120828
linjinkun楼主2024/9/21 22:59

我在做 https://www.luogu.com.cn/problem/P8815 这道题的时候学习了题解的做法(并非抄题解),但是始终拿不到题解里说的 5050 分部分分,只能拿到 2525 分,以下是我的两份评测记录:https://www.luogu.com.cn/record/177801379https://www.luogu.com.cn/record/177800693

2525 分代码:

#include<bits/stdc++.h>
using namespace std;
int len;
int cnt1,cnt2;//cnt1 = 或运算,cnt2 = 与运算
const int N = 1e6+1;
char a[N];
int dfs(int l,int r)
{
	int x = 0,yu = 0,huo = 0;
	for(int i = l;i<=r;i++)
	{
		if(a[i] == '(')
		{
			x++;
		}
		else
		{
			if(a[i] == ')')
			{
				x--;
			}
			else
			{
				if(!x)
				{
					if(a[i] == '|')
					{
						huo = i;
					}
					else
					{
					    if(a[i] == '&')
    					{
    						yu = i;
    					}
					}
				}
			}
		}
	}
	if(huo)
	{
		if(a[huo] == '|')
		{
			int sum1 = dfs(l,huo-1);
			if(sum1 == 1)
			{
				cnt1++;
				return 1;
			}
			else
			{
				int sum2 = dfs(huo+1,r);
				return (sum1|sum2);
			}
		}
	}
	if(yu)
	{
		if(a[yu] == '&')
		{
			int sum1 = dfs(l,yu-1);
			if(sum1 == 0)
			{
				cnt2++;
				return 0;
			}
			else
			{
				int sum2 = dfs(yu+1,r);
				return (sum1&sum2);
			}
		}
	}
	if(a[l] == '('&&a[r] == ')')
	{
		dfs(l+1,r-1);
	}
	else
	{
		return a[l]-'0';
	}
}
int main()
{
	scanf("%s",a+1);
	len = strlen(a+1);
	int s = dfs(1,len);
	printf("%d\n%d %d\n",s,cnt2,cnt1);
	return 0;
}

5050 分代码(题解的):

//测试题解
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define N (int)1e6 + 1
char str[N];
int sum1;
int sum2;
int dfs(int l,int r) {
    int x = 0,orpos = 0, andpos = 0;//记录括号层数、最后一个 | 出现的位置、最后一个 & 出现的位置
    for (int i = l; i<=r; ++i) {//遍历左右区间查找运算符
        if (str[i] == '(') {
            ++x;//增加一层括号
        }else {
            if (str[i] == ')') {
                --x;//减少一层括号
            }else {
                if (!x) {//不在括号中
                    if (str[i] == '|') {
                        orpos = i;
                    }else {
                        if (str[i] == '&') {
                            andpos = i;
                        }
                    }
                }
            }
        }
    }
    if (orpos) {//注意,因为 | 比 &优先级低,要先判断存不存在 |
        if (str[orpos] == '|') {
            int tmp1 = dfs(l, orpos - 1);//遍历左区间
            if (tmp1 == 1) {//如果是 1,触发了 | 短路
                ++sum1;
                return 1;//不需要计算右区间,直接返回 1
            }else {
                int tmp2 = dfs(orpos + 1, r);//计算右区间
                return (tmp1 | tmp2);
            }
        }
    }
    if (andpos) {
        if (str[andpos] == '&') {
            int tmp1 = dfs(l, andpos - 1);
            if (tmp1 == 0) {//如果是 0,触发了 & 短路
                ++sum2;
                return 0;//不需要计算右区间,直接返回 0
            }else {
                int tmp2 = dfs(andpos + 1, r);
                return (tmp1 & tmp2);
            }
        }
    }
    //不在括号内的运算符不存在
    if (str[l] == '(' && str[r] == ')') {//如果都被括号包裹着
        return dfs(l + 1, r - 1);//去掉括号
    }else {
        return str[l] - '0';//否则左右区间一定重合,返回数字就行了
    }
}
int main() {
    scanf("%s",str + 1);
    int len = strlen(str + 1);
    int sum = dfs(1, len);
    printf("%d\n%d %d\n",sum, sum2, sum1);//注意!一定要开个 sum 把dfs结果先记下来,否则直接输出会导致 UB
    return 0;
}

请问各位大佬,我的代码到底是什么原因没拿到 5050 分?

2024/9/21 22:59
加载中...