调题小记#01
先把代码挂出来吧
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int tim;
int rightn = 0;
int kpm;
char s1[10001][1001]; //s1为模板
char s2[10001][1001]; //s2是那家伙打的
int cnt[1001]; //每行字符计数
//先行内后行数
char tmp[10001];
int ptr;
int arr;
//1为模板,2为那家伙打的
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//读入模板
ptr = 1;
while(true){
cin.getline(tmp, 10001);
if(strlen(tmp) == 3 && tmp[0] == 'E' && tmp[1] == 'O' && tmp[2] == 'F'){
break;
}
else {
cnt[ptr] = strlen(tmp);
arr = 1;
for(int i = 0; i < strlen(tmp); i++){
if(tmp[i] == '<' && arr != 1){
arr--;
cnt[ptr] -= 2;
}
else{
s1[arr][ptr] = tmp[i];
arr++;
}
}
ptr++;
}
}
int n = ptr - 1; // n为输入行数
//读入那家伙打的
ptr = 1;
while(true){
cin.getline(tmp, 10001);
if(strlen(tmp) == 3 && tmp[0] == 'E' && tmp[1] == 'O' && tmp[2] == 'F'){
break;
}
else{
arr = 1;
for(int i = 0; i < strlen(tmp); i++){
if(tmp[i] == '<' && arr != 1){
arr--;
}
else{
s2[arr][ptr] = tmp[i];
arr++;
}
}
ptr++;
}
}
//比较
for(int k = 1; k <= n; k++){
for(int i = 1; i <= cnt[k]; i++){
if (s1[i][k] == s2[i][k]) rightn++;
}
}
cin >> tim;
kpm = rightn * 60 / tim;
cout << round(kpm);
return 0;
}
正如最顶部注释,这玩意只能拿50分(其实是40分,估计读入优化太差了而TLE了一个懒得调了)。
其实,这段代码已经经过了3次重构。第一次,用的栈,发现比较不会写(写了两次都炸了);第二次,回忆起双端队列,时间复杂度是开了O2也救不回来的那种。
现在是第三次,发现#6~#10总是wa,且都是比答案少1,怀疑是四舍五入写挂了,但是用了STL也是一样。
经过我2个小时的瞎猜苦心构造,终于发现"x<x<<x"型能使程序结果出错(没加特判,使得"<<"处会有一个<进入字符串)
原因?看到上面那个if了吗?
if(tmp[i] == '<' && arr != 1){
arr--;
cnt[ptr] -= 2;
}
else{
s1[arr][ptr] = tmp[i];
arr++;
如果此时arr已经为1,就会直接执行else{}中的代码,使得<跑到字符串里。
如何解决?加个特判试试?
f(tmp[i] == '<' && arr != 1){
arr--;
cnt[ptr] -= 2;
}
else if(tmp[i] == '<' && arr == 1){
continue;
}
else{
s1[arr][ptr] = tmp[i];
arr++;
目前来看,能解决待判文本中“x<x<<x”的问题,答案中的尚未解决。
2024.7.17留。
2024.7.18Update:睡醒之后清醒多了,发现处理答案时犯了低级错误:没有考虑到"<"并不是一个实体字符(仅限题目中),而strlen()会返回包含"<"数目的字符串长度。
弄完这个就90分了,剩下一个超时的点(无语,开了O2还变成RE)实在不想弄了,弄它得把整个输入部分用getchar()重写一遍不想写了属于是。
这么调一圈下来,这道题是我调试时间第二长的。(最长的是回文质数,当时调了整整3个月)

浙公网安备 33010602011771号