UVA 12657 Boxes in a Line
就是一个比较裸的双向链表的运用,只是处理的时候要注意,尤其是相邻的。
由于改BUG的时间较久,直接看注释就好了。
1 #include <stdio.h> 2 #include <string.h> 3 4 const int maxn = 1e5 + 10; 5 int left[maxn], right[maxn]; 6 int flag; 7 8 //这个题目我们在模拟的时候,貌似我又发现一个问题,就是我们这个题目的逻辑貌似只能有一个 9 //就是你不能正过来是一个规律,倒过来是一个规律,他们必须是一个逻辑的 10 //就是你倒过来的时候,逻辑也应该是倒过来的 11 //当然,可能也是错误的 12 //--9/30 bug1:我数组遍历结果的时候,终止条件应该是0,不应该是n+1 13 //--9/30 bug2:就是我进入第一次反转的时候,这里有个bug,就是如果我们根据他的下表来的话,会有bug,不如根据个数来 14 //--9/30 bug3:left和right数组应该初始化 15 //--10/11 最终BUG:161行代码判断,相邻,有两种,xy和yx,一开始我只讨论了一种 16 //历时一周多,终于改出来了 17 int main() 18 { 19 int n, m; 20 long long num[maxn]; 21 int kases = 1; 22 //freopen("f://duipai//data.txt","r",stdin); 23 //freopen("f://duipai//outwa.txt","w",stdout); 24 25 while(scanf("%d%d", &n, &m) == 2) 26 { 27 long long i; 28 long long sum = 0; 29 long long sum1 = 0; 30 memset(left, 0, sizeof(left)); 31 memset(right, 0, sizeof(right)); 32 33 //本题的双向链表我们采用带头节点的来模拟 34 for(i = 1; i <= n; i++) 35 { 36 num[i] = i; 37 sum1 += i; 38 } 39 40 left[1] = 0; 41 right[1] = 2; 42 right[0] = 1; 43 44 for(i = 2; i <= n - 1; i++) 45 { 46 left[i] = i - 1; 47 right[i] = i + 1; 48 } 49 left[n] = n - 1; 50 right[n] = n+1; //或者写0,这个具体还没有想好 51 left[n+1] = n; 52 53 int op, x, y; 54 flag = 0; //flag等于0说明这是正常序,flag等于1说明我们的顺序被我们倒过来了 55 //还有一点我们要记住的是,就是我们的left,right存的不是下标,而是实实在在的数值 56 for(i = 1; i <= m; i++) 57 { 58 scanf("%d", &op); 59 int temp1, temp2,temp3, temp4; 60 61 if(op == 1) 62 { 63 scanf("%d%d", &x, &y); //将x移到y的左边 64 //right[x-1] = temp1; ???x-1是他妈的什么鬼? 65 if(flag == 0) 66 { 67 if(right[x] == y) 68 { 69 //printf("~~~~\n"); 70 continue; 71 } 72 73 else 74 { 75 temp1 = right[x]; 76 temp2 = left[x]; 77 temp3 = left[y]; 78 temp4 = right[y]; 79 80 right[temp2] = temp1; 81 left[temp1] = temp2; 82 right[temp3] = x; 83 left[x] = temp3; 84 right[x] = y; 85 left[y] = x; 86 } 87 } 88 89 else if(flag == 1) //将x移动到y右边 90 { 91 if(left[x] == y) 92 continue; 93 else 94 { 95 temp1 = left[x]; 96 temp2 = right[x]; 97 temp3 = left[y]; 98 temp4 = right[y]; 99 100 right[temp1] = temp2; 101 left[temp2] = temp1; 102 left[temp4] = x; 103 right[x] = temp4; 104 right[y] = x; 105 left[x] = y; 106 } 107 } 108 } 109 110 else if(op == 2) //将x移动到y右边 111 { 112 scanf("%d%d", &x, &y); 113 114 if(flag == 0) 115 { 116 if(left[x] == y) 117 continue; 118 119 else 120 { 121 temp1 = left[x]; 122 temp2 = right[x]; 123 temp3 = left[y]; 124 temp4 = right[y]; 125 126 right[temp1] = temp2; 127 left[temp2] = temp1; 128 left[temp4] = x; 129 right[x] = temp4; 130 right[y] = x; 131 left[x] = y; 132 } 133 } 134 135 else if(flag == 1) //将x移动到y的左边 136 { 137 if(right[x] == y) 138 continue; 139 else 140 { 141 temp1 = right[x]; 142 temp2 = left[x]; 143 temp3 = left[y]; 144 temp4 = right[y]; 145 146 right[temp2] = temp1; 147 left[temp1] = temp2; 148 right[temp3] = x; 149 left[x] = temp3; 150 right[x] = y; 151 left[y] = x; 152 } 153 } 154 } 155 156 else if(op == 3) 157 { 158 scanf("%d%d", &x, &y); //意思就是我们x和y互相交换位置 159 //出现bug的原因是相邻的没有解决 160 if(flag == 0) 161 { 162 if(right[x] != y && left[y] != x && left[x] != y && right[y] != x) 163 { 164 temp1 = left[x]; 165 temp2 = right[x]; 166 temp3 = left[y]; 167 temp4 = right[y]; 168 169 right[temp1] = y; 170 left[y] = temp1; 171 right[y] = temp2; 172 left[temp2] = y; 173 174 right[temp3] = x; 175 left[x] = temp3; 176 right[x] = temp4; 177 left[temp4] = x; 178 } 179 180 else 181 { 182 if(right[x] == y) 183 { 184 temp1 = left[x]; 185 temp2 = right[y]; 186 right[temp1] = y; 187 left[y] = temp1; 188 right[y] = x; 189 left[x] = y; 190 right[x] = temp2; 191 left[temp2] = x; 192 continue; 193 } 194 195 else if(left[x] == y) 196 { 197 temp1 = left[y]; 198 temp2 = right[x]; 199 right[temp1] = x; 200 left[x] = temp1; 201 right[x] = y; 202 left[y] = x; 203 right[y] = temp2; 204 left[temp2] = y; 205 } 206 } 207 } 208 209 else if( flag == 1 ) 210 { 211 if(right[x] != y && right[y] != x) 212 { 213 temp1 = left[x]; //right[x] 214 temp2 = right[x]; //left[x] 215 temp3 = left[y]; //right[y] 216 temp4 = right[y]; //left[y] 217 218 left[temp2] = y; 219 right[y] = temp2; 220 left[y] = temp1; 221 right[temp1] = y; 222 223 left[x] = temp3; 224 right[temp3] = x; 225 right[x] = temp4; 226 left[temp4] = x; 227 } 228 229 else 230 { 231 if(right[x] == y) 232 { 233 temp1 = left[x]; 234 temp2 = right[y]; 235 right[temp1] = y; 236 left[y] = temp1; 237 right[y] = x; 238 left[x] = y; 239 right[x] = temp2; 240 left[temp2] = x; 241 continue; 242 } 243 244 else if(left[x] == y) 245 { 246 temp1 = left[y]; 247 temp2 = right[x]; 248 right[temp1] = x; 249 left[x] = temp1; 250 right[x] = y; 251 left[y] = x; 252 right[y] = temp2; 253 left[temp2] = y; 254 } 255 } 256 } 257 258 } 259 260 else if(op == 4) 261 { 262 flag = !flag; 263 264 if(flag == 1) 265 { 266 temp1 = left[n+1]; 267 temp2 = right[0]; 268 left[0] = temp1; 269 right[temp1] = 0; 270 right[n+1] = temp2; 271 left[temp2] = n + 1; 272 } 273 274 else if(flag == 0) 275 { 276 temp1 = left[0]; 277 temp2 = right[n+1]; 278 right[0] = temp2; 279 left[temp2] = 0; 280 right[temp1] = n+1; 281 left[n+1] = temp1; 282 283 } 284 } 285 } 286 287 if(flag == 0) //正常的顺序 288 { 289 i = right[0]; 290 long long j = left[n+1]; 291 //printf("数组的开头 %lld~~~~\n", i); 292 //printf("数组的结尾 %lld~~~~\n", j); 293 //printf("数组奇数位的数字: "); 294 if(n % 2 == 0) // n是偶数 295 { 296 int k; 297 for(k = 1; k <= n / 2;k++) 298 { 299 300 //printf("%lld ", i); 301 sum += i; 302 i = right[i]; 303 i = right[i]; 304 } 305 } 306 else if(n % 2 == 1) 307 { 308 int k; 309 for(k = 1; k <= (n+1) / 2; k++) 310 { 311 //printf("%lld ", i); 312 sum += i; 313 i = right[i]; 314 i = right[i]; 315 } 316 } 317 //printf("\n"); 318 319 printf("Case %d: %lld\n", kases++, sum); 320 } 321 322 else if(flag == 1) //倒过来的顺序 323 { 324 i = left[0]; 325 long long j = right[n+1]; 326 //printf("数组的开头 %lld~~~~\n", i); 327 //printf("数组的结尾 %lld~~~~\n", j); 328 //printf("数组奇数位的数字: "); 329 //printf("~~~%lld\n", left[n+1]); 330 if(n % 2 == 0) 331 { 332 int k; 333 for(k = 1; k <= n / 2; k++) 334 { 335 //printf("%lld ", i); 336 sum += i; 337 i = left[i]; 338 i = left[i]; 339 } 340 } 341 342 else if(n % 2 == 1) 343 { 344 int k; 345 for(k = 1; k <= (n+1) / 2; k++) 346 { 347 //printf("%lld ", i); 348 sum += i; 349 i = left[i]; 350 i = left[i]; 351 } 352 } 353 //printf("\n"); 354 printf("Case %d: %lld\n", kases++, sum); 355 } 356 } 357 return 0; 358 }