Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22835 | Accepted: 5398 |
Descriptionide
Inputspa
Outputcode
Sample Inputorm
7 15 4 100 15 25 2 175 2 25 5 175 2 25 5 0 0 10 35 500000000 200 500000000 0 0 3 255 1 10 1 255 2 10 1 255 2 10 1 255 1 0 0 0
Sample Outputblog
7 85 5 0 2 85 5 75 10 150 2 75 3 0 2 150 2 0 4 0 0 10 0 499999990 165 20 0 499999990 0 0 3 245 9 0 0 0
Hintip
Sourceget
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #define MAX_POINT_SERIES_NUM 1000 6 7 #define FAILURE (int)0xF 8 #define SUCCESS (int)0x0 9 10 #define TRUE (int)1 11 #define FALSE (int)0 12 13 #define MIN(a, b) (((a) < (b))?(a):(b)) 14 #define MAX(a, b) (((a) > (b))?(a):(b)) 15 16 typedef int BOOL; 17 18 typedef struct 19 { 20 int value; 21 long long num; 22 long long startIdx; 23 long long endIdx; 24 }PointSeries; 25 26 typedef struct 27 { 28 long long imageWide; 29 int pointsNum; 30 long long endIdx; 31 PointSeries points[MAX_POINT_SERIES_NUM]; 32 }Image; 33 34 Image g_input; 35 Image g_output; 36 37 int GetInputImage(Image *input) 38 { 39 int i = 0; 40 long long idx = 0; 41 PointSeries *points = NULL; 42 43 scanf("%I64d", &input->imageWide); 44 if(0 == input->imageWide) 45 { 46 printf("0\n"); 47 return FAILURE; 48 } 49 50 do 51 { 52 points = &input->points[i]; 53 scanf("%d %I64d", &points->value, &points->num); 54 points->startIdx = idx; 55 points->endIdx = idx + points->num - 1; 56 idx = idx + points->num; 57 i++; 58 }while(points->num != 0 && MAX_POINT_SERIES_NUM <= i); 59 60 input->endIdx = input->points[i-1].endIdx; 61 62 input->pointsNum = i; 63 return SUCCESS; 64 } 65 66 void PrintImage(Image *image) 67 { 68 int i; 69 printf("%I64d\n", image->imageWide); 70 for(i = 0; i < image->pointsNum; i++) 71 { 72 printf("%d %I64d\n", 73 image->points[i].value, 74 image->points[i].num); 75 } 76 if(image->imageWide != 0) printf("0 0\n"); 77 } 78 79 static int GetLeftDelta(long long wide, PointSeries *points, long long idx, PointSeries *cmpPoints) 80 { 81 PointSeries *lastPoints = NULL; 82 long long lastIdx = idx - 1; 83 84 if(idx % wide != 0 85 && lastIdx >= 0 86 && lastIdx < points->startIdx) 87 { 88 lastPoints = points-1; 89 return abs(lastPoints->value - cmpPoints->value); 90 } 91 92 return 0; 93 } 94 95 static int GetRightDelta(Image *input, PointSeries *points, long long idx, PointSeries *cmpPoints) 96 { 97 PointSeries *nextPoints = NULL; 98 long long nextIdx = idx + 1; 99 100 if(idx % input->imageWide != input->imageWide - 1 101 && points->endIdx < input->endIdx 102 && nextIdx > points->endIdx) 103 { 104 nextPoints = points+1; 105 return abs(nextPoints->value - cmpPoints->value); 106 } 107 108 return 0; 109 } 110 111 static int GetPointSeries(long long idx, long long endIdx, PointSeries **targetPoints) 112 { 113 PointSeries *points = (*targetPoints); 114 if(idx < 0 || idx > endIdx) return FAILURE; 115 116 while(1) 117 { 118 if(idx <= points->endIdx && points->startIdx <= idx) break; 119 120 if(idx > points->endIdx) 121 { 122 points++; 123 } 124 else if(idx < points->startIdx) 125 { 126 points--; 127 } 128 } 129 130 *targetPoints = points; 131 132 return SUCCESS; 133 } 134 135 static int GetOtherLineDelta(Image *input, PointSeries *orgPoints, long long idx) 136 { 137 int leftDelta, rightDelta, delta; 138 PointSeries *target = orgPoints; 139 140 if(FAILURE == GetPointSeries(idx, input->endIdx, &target)) return 0; 141 142 leftDelta = GetLeftDelta(input->imageWide, target, idx, orgPoints); 143 rightDelta = GetRightDelta(input, target, idx, orgPoints); 144 delta = abs(target->value - orgPoints->value); 145 146 delta = MAX(delta , leftDelta); 147 delta = MAX(delta , rightDelta); 148 149 return delta; 150 } 151 152 void SaveOutput(Image *output, int delta, long long num) 153 { 154 PointSeries *points = &output->points[output->pointsNum]; 155 156 if(num == 0) return; 157 158 if(output->pointsNum == 0) 159 { 160 points->num = num; 161 points->value = delta; 162 output->pointsNum = 1; 163 return; 164 } 165 166 if((points-1)->value != delta) 167 { 168 points->num = num; 169 points->value = delta; 170 output->pointsNum++; 171 } 172 else 173 { 174 (points-1)->num += num; 175 } 176 } 177 178 void ProcPoints(Image *input, PointSeries *points, long long num, int *rightDelta, long long *idx, Image *output) 179 { 180 long long j; 181 long long tmpIdx = *idx; 182 int leftDelta, upDelta, dowmDelta, delta; 183 int tmpRight = *rightDelta; 184 185 for(j = 0; j < num; j++) 186 { 187 leftDelta = tmpRight; 188 tmpRight = GetRightDelta(input, points, tmpIdx, points); 189 upDelta = GetOtherLineDelta(input, points, tmpIdx - input->imageWide); 190 dowmDelta = GetOtherLineDelta(input, points, tmpIdx + input->imageWide); 191 delta = MAX(leftDelta, tmpRight); 192 delta = MAX(delta, upDelta); 193 delta = MAX(delta, dowmDelta); 194 SaveOutput(output, delta, 1); 195 tmpIdx++; 196 } 197 *idx = tmpIdx; 198 *rightDelta = tmpRight; 199 } 200 201 void RowFastForward(Image *input, PointSeries *points, int *rightDelta, long long *idx, Image *output) 202 { 203 long long firstNum, secondNum, thridNum; 204 long long endIdx; 205 long long wide = input->imageWide; 206 207 if(*idx % wide == 0) 208 firstNum = wide; 209 else 210 firstNum = wide + 1; 211 212 ProcPoints(input, points, firstNum, rightDelta, idx, output); 213 214 if(points->endIdx % wide == wide - 1) 215 endIdx = points->endIdx - wide; 216 else 217 endIdx = points->endIdx - wide - 1; 218 219 secondNum = endIdx + 1 - points->startIdx - firstNum; 220 thridNum = points->endIdx - endIdx; 221 222 SaveOutput(output, 0, secondNum); 223 *idx += secondNum; 224 225 ProcPoints(input, points, thridNum, rightDelta, idx, output); 226 } 227 228 inline BOOL CanBeRowFastForward(long long pointsNum, long long imageWide) 229 { 230 if(pointsNum >= 4 * imageWide - 1) 231 { 232 return TRUE; 233 } 234 else 235 { 236 return FALSE; 237 } 238 } 239 240 inline BOOL CanBeSpecFastForward(PointSeries *points, long long wide) 241 { 242 if(points->num == 0 243 || points->num / wide == 0 244 || points->num % wide != 0 245 || (points+1)->num % wide != 0) 246 { 247 return FALSE; 248 } 249 return TRUE; 250 } 251 252 void SpecFastForward(PointSeries *points, long long wide, int *specDelta, Image *output) 253 { 254 int tmpDeta = *specDelta; 255 long long num, lineNum = points->num / wide; 256 257 num = (lineNum > 1) ? wide : 0; 258 259 SaveOutput(output, tmpDeta, num); 260 261 num = (lineNum > 2) ? ((lineNum - 2)*wide) : 0; 262 263 SaveOutput(output, 0, num); 264 265 if((points+1)->num != 0 && lineNum == 1) 266 { 267 tmpDeta = MAX(abs(points->value - (points+1)->value), tmpDeta); 268 } 269 else if((points+1)->num != 0 && lineNum > 1) 270 { 271 tmpDeta = abs(points->value - (points+1)->value); 272 } 273 else if((points+1)->num == 0 && lineNum > 1) 274 { 275 tmpDeta = 0; 276 } 277 278 SaveOutput(output, tmpDeta, wide); 279 280 *specDelta = tmpDeta; 281 } 282 283 void ProcImage(Image *input, Image *output) 284 { 285 long long i = 0, idx = 0; 286 int rightDelta = 0; 287 int specDelta = 0; 288 PointSeries *points = &input->points[0]; 289 290 if(input->pointsNum == 0) return; 291 292 while(CanBeSpecFastForward(points, input->imageWide)) 293 { 294 SpecFastForward(points, input->imageWide, &specDelta, output); 295 points++; 296 i++; 297 } 298 299 for(; i < input->pointsNum; i++) 300 { 301 points = &input->points[i]; 302 303 if(points->num <= 0) continue; 304 305 if(CanBeRowFastForward(points->num, input->imageWide)) 306 { 307 RowFastForward(input, points, &rightDelta, &idx, output); 308 } 309 else 310 { 311 ProcPoints(input, points, points->num, &rightDelta, &idx, output); 312 } 313 } 314 } 315 316 inline void InitOutputBuf(Image *input, Image *output) 317 { 318 output->pointsNum = 0; 319 output->imageWide = input->imageWide; 320 } 321 322 int main() 323 { 324 while(SUCCESS == GetInputImage(&g_input)) 325 { 326 InitOutputBuf(&g_input, &g_output); 327 ProcImage(&g_input, &g_output); 328 PrintImage(&g_output); 329 } 330 331 return 0; 332 }