我在做 https://www.luogu.com.cn/problem/P8815 这道题的时候学习了题解的做法(并非抄题解),但是始终拿不到题解里说的 50 分部分分,只能拿到 25 分,以下是我的两份评测记录:https://www.luogu.com.cn/record/177801379,https://www.luogu.com.cn/record/177800693。
25 分代码:
#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;
}
50 分代码(题解的):
//测试题解
#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;
}
请问各位大佬,我的代码到底是什么原因没拿到 50 分?