Назад к лучшим решениям Status: AC, problem DIP, contest ZFUN07. By tanakh (Hideyuki Tanaka), 2007-04-26 23:01:19.
  1. #include <cstdio>
  2. #include <memory.h>
  3. #include <algorithm>
  4. using namespace std;
  5.  
  6. #define MAXH 200
  7. #define MAXW 200
  8.  
  9. #define MERGIN 3
  10.  
  11. typedef int img[MAXH+MERGIN*2][MAXW+MERGIN*2];
  12.  
  13. #define at(bd,x,y) (bd[(y)+MERGIN][(x)+MERGIN])
  14.  
  15. int w,h,q;
  16.  
  17. void clear(img i,int v)
  18. {
  19. for (int y=0;y<MAXH+MERGIN*2;y++)
  20. for (int x=0;x<MAXW+MERGIN*2;x++)
  21. i[y][x]=v;
  22. }
  23. void cp(img s,img d)
  24. {
  25. memcpy(d,s,sizeof(img));
  26. }
  27.  
  28. inline int median(int *buf,int n)
  29. {
  30. if (n==0) return -1;
  31. if (n&1){
  32. int half=(n-1)/2;
  33. for (int i=0;i<=half;i++){
  34. int minv=buf[i],minj=i;
  35. for (int j=i+1;j<n;j++)
  36. if (buf[j]<minv)
  37. minv=buf[j],minj=j;
  38. swap(buf[i],buf[minj]);
  39. }
  40. return buf[half];
  41. }
  42. else{
  43. int half=n/2;
  44. for (int i=0;i<=half;i++){
  45. int minv=buf[i],minj=i;
  46. for (int j=i+1;j<n;j++)
  47. if (buf[j]<minv)
  48. minv=buf[j],minj=j;
  49. swap(buf[i],buf[minj]);
  50. }
  51. return (buf[half-1]+buf[half])/2;
  52. }
  53. }
  54.  
  55. inline int ssort(int *buf,int n)
  56. {
  57. for (int i=0;i<n-1;i++){
  58. int minv=buf[i],minj=i;
  59. for (int j=i+1;j<n;j++)
  60. if (buf[j]<minv)
  61. minv=buf[j],minj=j;
  62. swap(buf[i],buf[minj]);
  63. }
  64. }
  65.  
  66. void solve(img bd,img out)
  67. {
  68. static img org;
  69. cp(bd,org);
  70.  
  71. const int thh=16,thl=32;
  72. for (int y=0;y<h;y++){
  73. for (int x=0;x<w-1;x++){
  74. if (abs(at(bd,x,y)-at(bd,x+1,y))>thh)
  75. continue;
  76. if (y<h-1&&abs(at(bd,x,y)-at(bd,x,y+1))<=thh)
  77. continue;
  78. if (y>=1&&abs(at(bd,x,y)-at(bd,x,y-1))<=thh)
  79. continue;
  80. if (y<h-1&&abs(at(bd,x+1,y)-at(bd,x,y+1))<=thh)
  81. continue;
  82. if (y>=1&&abs(at(bd,x+1,y)-at(bd,x,y-1))<=thh)
  83. continue;
  84. int base=(at(bd,x,y)+at(bd,x+1,y))/2;
  85. int len=2;
  86. int skip=0;
  87. int tx=x+2;
  88. while(skip<=2&&tx<w){
  89. if (abs(at(bd,tx,y)-base)<=thh)
  90. skip=0;
  91. else
  92. skip++;
  93. tx++;
  94. len++;
  95. }
  96. if (len>=thl){
  97. int b1=at(bd,x,y),b2=at(bd,x+1,y);
  98. for (int cx=x+2;cx<tx-skip;cx++){
  99. if (abs(at(bd,cx,y)-base)<=thh)
  100. b1=b2,b2=at(bd,cx,y);
  101. else
  102. at(bd,cx,y)=(b1+b2)/2;
  103. }
  104. x=tx-1;
  105. }
  106. }
  107. }
  108. for (int x=0;x<w;x++){
  109. for (int y=0;y<h-1;y++){
  110. if (abs(at(bd,x,y)-at(bd,x,y+1))>thh)
  111. continue;
  112. if (x<w-1&&abs(at(bd,x,y)-at(bd,x+1,y))<=thh)
  113. continue;
  114. if (x>=1&&abs(at(bd,x,y)-at(bd,x-1,y))<=thh)
  115. continue;
  116. if (x<w-1&&abs(at(bd,x,y+1)-at(bd,x+1,y))<=thh)
  117. continue;
  118. if (x>=1&&abs(at(bd,x,y+1)-at(bd,x-1,y))<=thh)
  119. continue;
  120. int base=(at(bd,x,y)+at(bd,x,y+1))/2;
  121. int len=2;
  122. int skip=0;
  123. int ty=y+2;
  124. while(skip<=2&&ty<h){
  125. if (abs(at(bd,x,ty)-base)<=thh)
  126. skip=0;
  127. else
  128. skip++;
  129. ty++;
  130. len++;
  131. }
  132. if (len>=thl){
  133. int b1=at(bd,x,y),b2=at(bd,x,y+1);
  134. for (int cy=y+2;cy<ty-skip;cy++){
  135. if (abs(at(bd,x,cy)-base)<=thh)
  136. b1=b2,b2=at(bd,x,cy);
  137. else
  138. at(bd,x,cy)=(b1+b2)/2;
  139. }
  140. y=ty-1;
  141. }
  142. }
  143. }
  144. /*
  145. if (0){
  146. for (int y=0;y<h;y++)
  147. for (int x=0;x<w;x++)
  148. if (at(bd,x,y)==at(org,x,y))
  149. at(out,x,y)=at(bd,x,y);
  150. else
  151. at(out,x,y)=256;
  152. }
  153. else
  154. cp(bd,out);
  155. return;
  156. */
  157. static img med;
  158.  
  159. for (int y=0;y<h;y++){
  160. for (int x=0;x<w;x++){
  161. static const int vect[18]={0,0, 0,1,1,0, 0,-1,-1,0, 1,1,-1,-1,1,-1,-1,1};
  162. int tmp[9],tmpc=0;
  163. for (int i=0;i<5;i++)
  164. tmp[tmpc++]=at(bd,x+vect[i*2],y+vect[i*2+1]);
  165. at(med,x,y)=median(tmp,tmpc);
  166. }
  167. }
  168.  
  169. for (int y=0;y<h;y++){
  170. for (int x=0;x<w;x++){
  171. int tmp[9],tmpc=0;
  172. for (int dx=-1;dx<=1;dx++)
  173. for (int dy=-1;dy<=1;dy++)
  174. if (!(dx==0&&dy==0)){
  175. int nx=x+dx,ny=y+dy;
  176. if (nx>=0&&nx<w&&ny>=0&&ny<h)
  177. tmp[tmpc++]=at(bd,x+dx,y+dy);
  178. }
  179. ssort(tmp,tmpc);
  180. int mdif=tmp[tmpc-1]-tmp[0];
  181.  
  182. bool b=false;
  183. if (mdif<32&&abs(at(bd,x,y)-tmp[tmpc/2])>mdif)
  184. b=true;
  185. if (tmpc==9&&
  186. (tmp[tmpc-2]-tmp[0]<32||
  187. tmp[tmpc-1]-tmp[1]<32)&&
  188. abs(at(bd,x,y)-tmp[tmpc/2])>32)
  189. b=true;
  190.  
  191. if (b)
  192. at(bd,x,y)=at(med,x,y);
  193. }
  194. }
  195.  
  196. static img f;
  197. clear(f,0);
  198. for (int y=0;y<h;y++){
  199. for (int x=0;x<w;x++){
  200. static const int vect[8]={0,1,1,0,0,-1,-1,0};
  201. int cnt=0,cnt2=0,cnt3=0;
  202. for (int i=0;i<4;i++){
  203. int nx=x+vect[i*2];
  204. int ny=y+vect[i*2+1];
  205. if (!(nx>=0&&nx<w&&ny>=0&&ny<h))
  206. continue;
  207. int tmp=at(bd,x,y)-at(bd,nx,ny);
  208. if (tmp>=92) cnt++;
  209. if (tmp<=-92) cnt--;
  210. if (tmp>=64) cnt2++;
  211. if (tmp<=-64) cnt2--;
  212. cnt3++;
  213. }
  214. if (cnt>=cnt3-1||cnt<=-(cnt3-1)||cnt2==cnt3||cnt2==-cnt3)
  215. at(f,x,y)=1;
  216. }
  217. }
  218. for (int y=0;y<h;y++)
  219. for (int x=0;x<w;x++)
  220. if (at(f,x,y))
  221. at(bd,x,y)=at(med,x,y);
  222.  
  223. static img err;
  224. static int lev[512];
  225. memset(lev,0,sizeof(lev));
  226. for (int y=0;y<h;y++){
  227. for (int x=0;x<w;x++){
  228. int minest=256;
  229. for (int i=0;i<4;i++){
  230. static const int vect[8]={0,1,1,0,0,-1,-1,0};
  231. int nx=x+vect[i*2];
  232. int ny=y+vect[i*2+1];
  233. int mx=x+vect[i*2]*2;
  234. int my=y+vect[i*2+1]*2;
  235. if (!(mx>=0&&mx<w&&my>=0&&my<h))
  236. continue;
  237. int nn=at(bd,nx,ny);
  238. int mm=at(bd,mx,my);
  239. int est=nn+(nn-mm);
  240. int eee=abs(at(bd,x,y)-est);
  241.  
  242. minest<?=eee;
  243. }
  244. for (int i=0;i<4;i++){
  245. static const int vect[8]={0,1,1,0, 1,1,1,-1};
  246. int nx=x+vect[i*2];
  247. int ny=y+vect[i*2+1];
  248. int mx=x-vect[i*2];
  249. int my=y-vect[i*2+1];
  250. if (!(nx>=0&&nx<w&&ny>=0&&ny<h))
  251. continue;
  252. if (!(mx>=0&&mx<w&&my>=0&&my<h))
  253. continue;
  254. int nn=at(bd,nx,ny);
  255. int mm=at(bd,mx,my);
  256. int est=(nn+mm)/2;
  257. int eee=abs(at(bd,x,y)-est);
  258.  
  259. minest<?=eee;
  260. }
  261. at(err,x,y)=minest;
  262. lev[at(err,x,y)]++;
  263. }
  264. }
  265.  
  266. int found=0;
  267. for (int y=0;y<h;y++)
  268. for (int x=0;x<w;x++)
  269. if (at(bd,x,y)!=at(org,x,y))
  270. found++;
  271.  
  272. int th=512;
  273. int es=(w*h*q-found)/325,acc=0;
  274. for (int i=511;i>=0;i--){
  275. if (acc<=es) th=i;
  276. acc+=lev[i];
  277. }
  278.  
  279. for (int y=0;y<h;y++){
  280. for (int x=0;x<w;x++){
  281. if (at(err,x,y)>=th)
  282. at(bd,x,y)=at(med,x,y);
  283. else
  284. at(bd,x,y)=at(bd,x,y);
  285. }
  286. }
  287. cp(bd,org);
  288.  
  289. for (int y=0;y<h;y++){
  290. for (int x=0;x<w;x++){
  291. int tmp[9],tmpc=0;
  292. for (int dy=-1;dy<=1;dy++)
  293. for (int dx=-1;dx<=1;dx++){
  294. int nx=x+dx,ny=y+dy;
  295. if (nx>=0&&nx<w&&ny>=0&&ny<h)
  296. tmp[tmpc++]=at(bd,x+dx,y+dy);
  297. }
  298. at(med,x,y)=median(tmp,tmpc);
  299. }
  300. }
  301.  
  302. for (int y=0;y<h;y++){
  303. for (int x=0;x<w;x++){
  304. int tmp[9],tmpc=0;
  305. for (int dx=-1;dx<=1;dx++)
  306. for (int dy=-1;dy<=1;dy++)
  307. if (!(dx==0&&dy==0)){
  308. int nx=x+dx,ny=y+dy;
  309. if (nx>=0&&nx<w&&ny>=0&&ny<h)
  310. tmp[tmpc++]=at(bd,x+dx,y+dy);
  311. }
  312. ssort(tmp,tmpc);
  313. int mdif=tmp[tmpc-1]-tmp[0];
  314.  
  315. bool b=false;
  316. if (mdif<32&&abs(at(bd,x,y)-tmp[tmpc/2])>mdif)
  317. b=true;
  318. if ((tmp[tmpc-2]-tmp[0]<32||
  319. tmp[tmpc-1]-tmp[1]<32)&&
  320. abs(at(bd,x,y)-tmp[tmpc/2])>32)
  321. b=true;
  322.  
  323. if (b){
  324. at(bd,x,y)=at(med,x,y);
  325. found++;
  326. }
  327. }
  328. }
  329.  
  330. if (0){
  331. for (int y=0;y<h;y++)
  332. for (int x=0;x<w;x++)
  333. if (at(bd,x,y)==at(org,x,y))
  334. at(out,x,y)=at(bd,x,y);
  335. else
  336. at(out,x,y)=256;
  337. }
  338. else
  339. cp(bd,out);
  340. }
  341.  
  342. int main()
  343. {
  344. int cases;scanf("%d",&cases);
  345. while(cases--){
  346. scanf("%d%d%d",&q,&h,&w);
  347.  
  348. static img bd;clear(bd,0);
  349. for (int y=0;y<h;y++)
  350. for (int x=0;x<w;x++)
  351. scanf("%d",&at(bd,x,y));
  352.  
  353. img out;
  354. solve(bd,out);
  355.  
  356. printf("%d %d\n",h,w);
  357. for (int y=0;y<h;y++){
  358. for (int x=0;x<w;x++)
  359. printf(" %03d",at(out,x,y));
  360. puts("");
  361. }
  362. }
  363. return 0;
  364. }