题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2054
这是目前以来我写的最长的代码!所以看到这篇报告的读者,如果自问耐心不是过人的话,还是不要看代码了,建议只看思路。这是很久以前遗留下来的题目,wa了一次之后就放下了,因为知道会很繁琐,不是单纯短短几行代码就搞定的(那时天真的做法啊~~)。几天前,心血来潮,决定把它干掉!!!前前后后做了足足3天,其实没那么夸张啦,加起来应该7、8个小时左右吧(不好意思,说了那么多废话),步入正题。
这道题目题意很简单:就是判别A是否等于B。不过有很多细节需要注意,我就是看着人家给的测试数据才知道的,辛辛苦苦地写出来,提交之后遇到我有史以来的第一个Runtime Error(ACCESS_VIOLATION),什么来的,百度之......RE一般有几种情况:1)数组越界 2)访问非法内存(什么来的?) 3)除以0 4)堆栈溢出...... 我十分确定是第2种情况,但是我不知道如何查错,于是请教乌冬师兄,超级好人,叫我发代码来(N长的都愿意看,真的是感动万分啊~~),原来是用了goto语句。之所以用goto,是因为觉得不需要用太多标志变量,break只能跳一重循环,而goto可以跳几重。还有一个致命的错误是,goto(用了两次)的出口用了两个相同的变量h,不过在不同的函数块里。他说goto语句是全局跳跃,会破坏整体结构,说用goto是坏习惯,建议用break,能跳出最近一个循环 ,或者return(长见识了,好感动)。删掉之后,wa了。因为有很多变态的数据过不了!!!
题目的解决思路大体上是:1、正负号问题 2、前导0 3、后置0
还有一些特别的输入要考虑,输入的第一个字符是 . 的情况,这里我是把它放在正负号的函数里解决的。最折磨我的是几种情况没考虑到
1、len1(a的长度),len2(b的长度)是变化的!!因为在解决这些小问题的过程中,有可能增添数据(例如,.1234变成0.1234,长度就增加1),或者消去数据(000.456变成0.456,长度减少2)
2、由基础不扎实导致的!字符'0'、0、'\0'(C++中字符串的结尾标志,存储在字符串的结尾)要区分清楚。上面已经提到len是会改变的,也就是字符型数组的长度是会变的,因此结尾要赋予0,作为字符串的结尾标志。字符'0'是当.123变0.123的时候才用到的。
在网上看到其实只需要处理很少情况就可以AC的,不过为了严谨,我就很啰嗦地考虑了很多种情况。discuss中很奇葩的数据都过了。以下是AC代码:
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 5 const int MAXN = 100000 + 10; //MAXN的长度要足够大,少一个0都不行 6 char a[MAXN], b[MAXN]; 7 bool asign, bsign; //记录a、b的正负号 8 int len1, len2; 9 10 void as() 11 { 12 int i; 13 if (a[0] == '-' || a[0] == '+') 14 { 15 if (a[0] == '-') 16 asign = false; 17 else 18 asign = true; 19 for (i = 0; i < len1-1; i++) //新的数组不要存储符号 20 a[i] = a[i+1]; 21 a[i] = 0; //赋予数组结束标志 22 len1--; //少了符号位长度减1 23 } 24 if (a[0] == '.') 25 { 26 for (i = len1; i >= 1; i--) //整个数组向后移,为首位插入字符0做准备 27 a[i] = a[i-1]; 28 a[i] = '0'; 29 len1++; //多了字符0之后长度加1 30 } 31 if (isdigit(a[0])) //没正负号的表示是正数 32 asign = true; 33 /* cout << "a[j] = " << a << endl; 34 cout << "alen = " << len1 << endl; */ 35 } 36 37 void bs() 38 { 39 int i; 40 if (b[0] == '-' || b[0] == '+') 41 { 42 if (b[0] == '-') 43 bsign = false; 44 else 45 bsign = true; 46 for (i = 0; i < len2-1; i++) 47 b[i] = b[i+1]; 48 b[i] = 0; 49 len2--; 50 } 51 if (b[0] == '.') 52 { 53 for (i = len2; i >= 1; i--) 54 b[i] = b[i-1]; 55 b[i] = '0'; 56 len2++; 57 } 58 if (isdigit(b[0])) 59 bsign = true; 60 /* cout << "b[j] = " << b << endl; 61 cout << "blen = " << len2 << endl; */ 62 } 63 64 void a_beforzero() 65 { 66 int i, j, pos, count; 67 i = count = 0; //count的设置很重要,用了统计去掉多少个前导0 68 while (a[i] == '0') 69 { 70 i++; 71 count++; 72 } 73 pos = i; 74 j = 0; 75 if (!isdigit(a[i])) //a[i] = '.’的情况 76 { 77 a[j++] = '0'; 78 for ( ; pos < len1; pos++) 79 a[j++] = a[pos]; 80 len1++; 81 } 82 else 83 { 84 while (pos < len1) 85 a[j++] = a[pos++]; 86 } 87 a[j] = 0; 88 len1 -= count; 89 /* cout << "a[j] = " << a << endl; 90 cout << "alen = " << len1 << endl; */ 91 } 92 93 void b_beforzero() 94 { 95 int i, j, pos, count; 96 i = count = 0; 97 while (b[i] == '0') 98 { 99 i++; 100 count++; 101 } 102 pos = i; 103 j = 0; 104 if (!isdigit(b[i])) 105 { 106 b[j++] = '0'; 107 for ( ; pos < len2; pos++) 108 b[j++] = b[pos]; 109 len2++; 110 } 111 else 112 { 113 while (pos < len2) 114 b[j++] = b[pos++]; 115 } 116 b[j] = 0; 117 len2 -= count; 118 /* cout << "b[j] = " << b << endl; 119 cout << "blen = " << len2 << endl; */ 120 } 121 122 void a_backzero() 123 { 124 int i, j; 125 for (i = 0; i < len1; i++) 126 { 127 if (a[i] == '.') 128 { 129 j = len1-1; 130 while (a[j] == '0') 131 j--; 132 if (a[j] == '.' ) //去掉后置0有可能是123.的情况,此时要在'.'的位置增添结束标志 133 a[j] = 0; 134 else 135 a[++j] = 0; //是数字的情况就在后一位加结束标志 136 break; 137 } 138 } 139 /* cout << "a[j] = " << a << endl; 140 cout << "alen = " << len1 << endl; */ 141 } 142 143 void b_backzero() 144 { 145 int i, j; 146 for (i = 0; i < len2; i++) 147 { 148 if (b[i] == '.') 149 { 150 j = len2-1; 151 while (b[j] == '0') 152 j--; 153 if (b[j] == '.') 154 b[j] = 0; 155 else 156 b[++j] = 0; 157 break; 158 } 159 } 160 /* cout << "b[j] = " << b << endl; 161 cout << "blen = " << len2 << endl; */ 162 } 163 164 int main() 165 { 166 while (scanf("%s%s", a, b) != EOF) 167 { 168 len1 = strlen(a); 169 len2 = strlen(b); 170 as(); 171 bs(); 172 a_beforzero(); 173 b_beforzero(); 174 a_backzero(); 175 b_backzero(); 176 if (asign == bsign && strcmp(a, b) == 0) 177 printf("YES\n"); 178 else 179 printf("NO\n"); 180 memset(a, 0, sizeof(a)); 181 memset(b, 0, sizeof(b)); 182 } 183 return 0; 184 }