Назад к лучшим решениям Status: AC, problem ZDIP, contest ZEL07. By majac (Andrey Maksimenko), 2007-03-13 13:29:07.
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <memory.h>
  4.  
  5.  
  6. //#define DEBUG_DATA_OUT 1
  7.  
  8. #define MAX_WIDTH 200
  9. #define MAX_HEIGHT 200
  10. #define FILT_RAD 2
  11. int Q,H,W;
  12. int weight[5][5] = { { 0,1,2,1,0 },
  13. { 1,5,8,5,1 },
  14. { 2,8,10,8,2 },
  15. { 1,5,8,5,1 },
  16. { 0,1,2,1,0 }
  17. };
  18. #define IMGVAL_MAX 256
  19. #define NOISEVAL_MAX 1000
  20.  
  21. int img[200][200];
  22. int noise[200][200];
  23. int noise1[200][200];
  24. int noise_hit[200][200];
  25.  
  26. int noiselev_cnt[NOISEVAL_MAX];
  27.  
  28. #define SIM_DELTA 20
  29. #define DIF_DELTA 70
  30. #define VALID_TRESHOLD 600
  31.  
  32. void print_arr(int *arr,int Width, int Height)
  33. { int i,j;
  34. for (j=0; j<Height; j++)
  35. { for (i=0; i<Width; i++)
  36. printf("%3d ",arr[MAX_WIDTH*j+i]);
  37. printf("\n");
  38. }
  39. }
  40.  
  41. __inline int abs(int val)
  42. { return val < 0 ? -val : val;
  43. }
  44.  
  45.  
  46. void highpass(int expected,int *filtlev)
  47. { int total = 0;
  48. int lev = 0;
  49. #ifdef DEBUG_DATA_OUT
  50. printf("HIGHPASS expected = %d\n",expected);
  51. #endif
  52. for (lev=999; lev>=0 && total*100 < expected ; lev--)
  53. { total += noiselev_cnt[lev];
  54. /*#ifdef DEBUG_DATA_OUT
  55. printf("lev = %d cnt = %d | total = %d\n",lev,noiselev_cnt[lev],total);
  56. #endif*/
  57. }
  58. if ( total*100 > expected )
  59. lev++;
  60. if (lev<0)
  61. lev = 0;
  62. *filtlev = lev;
  63. #ifdef DEBUG_DATA_OUT
  64. printf("HIGHPASS filtlev = %d\n",lev);
  65. #endif
  66. }
  67.  
  68. void colregion_hit(int regstart,int regwidth,int Width,int Height)
  69. { int i,j;
  70. int expected,filtlev;
  71. #ifdef DEBUG_DATA_OUT
  72. printf("COLREGION_HIT regstart = %d regwidth = %d\n",regstart,regwidth);
  73. #endif
  74. memset(noiselev_cnt,0,sizeof(noiselev_cnt));
  75. for (j=0; j<Height; j++)
  76. { for (i=0; i<Width; i++)
  77. { if ( img[j][i]>= regstart && img[j][i]<= regstart+regwidth )
  78. { noiselev_cnt[noise[j][i]]++;
  79. }
  80. }
  81. }
  82. expected = H*W*Q*regwidth/IMGVAL_MAX;
  83. highpass(expected,&filtlev);
  84. for (j=0; j<Height; j++)
  85. { for (i=0; i<Width; i++)
  86. { if ( img[j][i]>= regstart && img[j][i]<= regstart+regwidth )
  87. { noise_hit[j][i]++;
  88. if ( noise[j][i] > filtlev )
  89. noise1[j][i] += noise[j][i];
  90. else if ( noise[j][i] > 2*filtlev/3 )
  91. noise1[j][i] += noise[j][i] - 2*filtlev/3;
  92. }
  93. }
  94. }
  95. }
  96.  
  97. void colregion(int Width,int Height)
  98. { int size,k;
  99. memset(noise1,0,sizeof(noise1));
  100. memset(noise_hit,0,sizeof(noise_hit));
  101. size = 15;
  102. for (k=0; k+size < IMGVAL_MAX; k+= size+1)
  103. { colregion_hit(k,size,Width,Height);
  104. }
  105. }
  106.  
  107.  
  108. int gaussfilter(int x,int y,int *estval,int *valid,int *nsim,int *ndif)
  109. { int i,j;
  110. int estimate = 0, importance = 0, weightsum = 0;
  111. int est_valid = 0, center_valid;
  112. int thisval,neighval;
  113. int imp, wght;
  114. int centerimp;
  115. *ndif = 0; *nsim = 0;
  116. thisval = img[y][x];
  117. for ( j=-FILT_RAD; j<=FILT_RAD; j++ )
  118. { if ( y+j >= 0 && y+j < MAX_HEIGHT )
  119. for ( i=-FILT_RAD; i<=FILT_RAD; i++ )
  120. { if ( x+i >= 0 && x+i < MAX_WIDTH )
  121. { neighval = img[y+j][x+i];
  122. wght = weight[j+FILT_RAD][i+FILT_RAD];
  123. weightsum += wght;
  124. imp = wght* ( NOISEVAL_MAX - noise[y+j][x+i] );
  125. importance += imp;
  126. estimate += imp*neighval;
  127. if ( ! (i==0 && j==0) )
  128. if ( NOISEVAL_MAX - noise[y+j][x+i] > VALID_TRESHOLD )
  129. { if ( abs(thisval-neighval) < SIM_DELTA )
  130. (*nsim) +=100*wght;
  131. if ( abs(thisval-neighval) > DIF_DELTA )
  132. (*ndif) +=100*wght;
  133. }
  134. }
  135. }
  136. }
  137. //&#1074;&#1099;&#1095;&#1080;&#1089;&#1083;&#1103;&#1077;&#1084; &#1074;&#1082;&#1083;&#1072;&#1076; &#1094;&#1077;&#1085;&#1090;&#1088;&#1072;&#1083;&#1100;&#1085;&#1086;&#1081; &#1090;&#1086;&#1095;&#1082;&#1080; &#1074; &#1091;&#1082;&#1072;&#1079;&#1072;&#1085;&#1085;&#1099;&#1077; &#1089;&#1091;&#1084;&#1084;&#1099;
  138. wght = weight[0+FILT_RAD][0+FILT_RAD];
  139. centerimp = wght* ( NOISEVAL_MAX - noise[y][x] );
  140. weightsum -= wght;
  141. importance -= centerimp;
  142. estimate -= centerimp*img[y][x];
  143. estimate /= importance;
  144. *nsim /= weightsum;
  145. *ndif /= weightsum;
  146. est_valid = importance/weightsum;
  147. center_valid = NOISEVAL_MAX - noise[y][x];
  148. *estval = estimate;
  149. *valid = est_valid;
  150. return 1;
  151. }
  152.  
  153. int main()
  154. { int Ntest,test,pass;
  155. int x,y;
  156. int filtered,diff,filt_valid,cent_valid,nsim,ndif;
  157. int filtlev,expected,total;
  158. scanf("%d",&Ntest);
  159. for (test=1; test<=Ntest; test++)
  160. { scanf("%d %d %d",&Q,&H,&W);
  161. expected = Q*H*W;
  162. for (y=0; y<H; y++)
  163. for (x=0; x<W; x++)
  164. { scanf("%d",&(img[y][x]));
  165. }
  166. memset(noise,0,sizeof(noise));
  167. memset(noise1,0,sizeof(noise1));
  168. for (pass=0; pass<5; pass++)
  169. {
  170. #ifdef DEBUG_DATA_OUT
  171. printf("PASS NUMBER %d\n",pass);
  172. #endif
  173. memset(noiselev_cnt,0,sizeof(noiselev_cnt));
  174. for (y=0; y<H; y++)
  175. { for (x=0; x<W; x++)
  176. { gaussfilter(x,y,&filtered,&filt_valid,&nsim,&ndif);
  177. cent_valid = NOISEVAL_MAX-noise[y][x];
  178. diff = abs(filtered-img[y][x]);
  179. #ifdef DEBUG_DATA_OUT
  180. printf("%d %d v(%d %d) n(%d %d) ",filtered,noise[y][x],filt_valid,cent_valid,nsim,ndif);
  181. #endif
  182. if (nsim < 30)
  183. noise1[y][x] = (30-nsim)*25 + diff;
  184. if (ndif > 85)
  185. noise1[y][x] += (100-ndif)*30 + diff;
  186. if (noise1[y][x]<0)
  187. noise1[y][x] = 0;
  188. if (noise1[y][x]>=NOISEVAL_MAX)
  189. noise1[y][x] = NOISEVAL_MAX-1;
  190. noiselev_cnt[noise1[y][x]]++;
  191. }
  192. #ifdef DEBUG_DATA_OUT
  193. printf("\n");
  194. #endif
  195. }
  196. #ifdef DEBUG_DATA_OUT
  197. printf("NOISE1 before COLREGION\n");
  198. print_arr(&(noise1[0][0]),W,H);
  199. #endif
  200. memcpy(noise,noise1,sizeof(noise1));
  201. memset(noise1,0,sizeof(noise1));
  202. colregion(W,H);
  203. #ifdef DEBUG_DATA_OUT
  204. printf("NOISE1 after COLREGION\n");
  205. print_arr(&(noise1[0][0]),W,H);
  206. #endif
  207. /*
  208. #ifdef DEBUG_DATA_OUT
  209. printf("NOISE1 before HIGH_PASS_FILTER\n");
  210. print_arr(&(noise1[0][0]),W,H);
  211. printf("expected = %d\n",expected);
  212. #endif
  213. total = 0;
  214. for (filtlev=999; filtlev>=0 && total*100 < expected ; filtlev--)
  215. { total += noiselev_cnt[filtlev];
  216. #ifdef DEBUG_DATA_OUT
  217. printf("lev = %d cnt = %d | total = %d\n",filtlev,noiselev_cnt[filtlev],total);
  218. #endif
  219. }
  220. if ( total*100 > expected )
  221. filtlev++;
  222. if (filtlev<0)
  223. filtlev = 0;
  224. for (y=0; y<H; y++)
  225. { for (x=0; x<W; x++)
  226. { if (noise1[y][x]<=filtlev)
  227. noise1[y][x]=0;
  228. }
  229. }
  230. #ifdef DEBUG_DATA_OUT
  231. printf("NOISE1 after HIGH_PASS_FILTER\n");
  232. print_arr(&(noise1[0][0]),W,H);
  233. #endif
  234. */
  235. memcpy(noise,noise1,sizeof(noise1));
  236. memset(noise1,0,sizeof(noise1));
  237. }
  238. printf("%d %d\n",H,W);
  239. for (y=0; y<H; y++)
  240. { for (x=0; x<W; x++)
  241. { if ( noise[y][x] > 50 )
  242. { gaussfilter(x,y,&filtered,&filt_valid,&nsim,&ndif);
  243. printf("%d ",filtered);
  244. }
  245. else
  246. printf("%d ",img[y][x]);
  247. }
  248. printf("\n");
  249. }
  250. }
  251.  
  252. return 0;
  253. }