不得不說codeforces上的題目,思維真的很活躍。
上一期的A題,寫了那麼多,這個題我也用最樸實的想法來寫的時候,發現超時了!!!【代碼二】
有提交錯誤時的測試數據得出:輸出的數據只有2種可能“2”和“4”
經過對題目的本質的分析,題目的格子處理只有2種可能:
<1>“好格子”都在中間,選任意一個“好格子”,需要塗4次,可將棋盤全部塗滿;
<2>“存在”位於邊界的“好格子”,選任意一個邊界上的“好格子”,需要塗2次即可將棋盤全部塗滿。
找到本質後,題目就是“so easy!”!
對輸入的棋盤的“好格子”的情況進行處理,要是有處於邊界上的“好格子”,直接輸出“2”;否則,直接輸出“4”。
(見【代碼一】)
【代碼一】
#include<stdio.h> int main() { int n,m; int u; int i,j; while(scanf("%d%d",&n,&m)!=EOF) { int flag=0; for(i=0;i<n;i++) for(j=0;j<m;j++) { scanf("%d",&u); if(u) if(i==0||i==n-1||j==0||j==m-1) //邊界有good cell flag++; } if(flag)printf("2\n"); else printf("4\n"); } return 0; }
【代碼二
//Warnning:This is the TLE code , please don't copy it for study! #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int n,m; //the size of the table int map[52][52]; //the table ,the "0" is where wait for paint int gn; //good point number int sum; //all the number of point need to be paint int ans; //the step to paint all the point ,the ans what we need int x1,y1,x2,y2; struct node //the infromation of the good point { int x; int y; int max; //the max point can paint if we choice this good point int maxdir; //the direction the max point can paint1 2 // 3 4 }gp[2500]; bool cmp(node a,node b) //to sort the good point by it's max point can be paint { return b.max-a.max; } void initial() //initial the infromations { int u; int i,j; ans=0; sum=n*m; gn=0; memset(map,0,sizeof(map)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&u); if(u) { gp[gn].x=i; gp[gn].y=j; gn++; } } } void chang() //choice one good point and paint some point { int i,j; sum-=gp[0].max; if(gp[0].maxdir==1) { x1=1;x2=gp[0].x; y1=1;y2=gp[0].y; } else if(gp[0].maxdir==2) { x1=1;x2=gp[0].x; y1=gp[0].y;y2=m; } else if(gp[0].maxdir==3) { x1=gp[0].x;x2=n; y1=1;y2=gp[0].y; } else { x1=gp[0].x;x2=n; y1=gp[0].y;y2=m; } for(i=x1;i<=x2;i++) for(j=y1;j<=y2;j++) map[i][j]=1; } int cout1() { int cou=0; int i,j; for(i=x1;i<=x2;i++) for(j=y1;j<=y2;j++) if(!map[i][j])cou++; return cou; } void updata() //updata all the point number the good point can paint { int i,j,k; int maxn; for(k=0;k<gn;k++) { gp[k].max=0; x1=1;x2=gp[0].x; y1=1;y2=gp[0].y; maxn=cout1(); if(maxn>gp[k].max) { gp[k].max=maxn; gp[k].maxdir=1; } x1=1;x2=gp[0].x; y1=gp[0].y;y2=m; maxn=cout1(); if(maxn>gp[k].max) { gp[k].max=maxn; gp[k].maxdir=2; } x1=gp[0].x;x2=n; y1=1;y2=gp[0].y; maxn=cout1(); if(maxn>gp[k].max) { gp[k].max=maxn; gp[k].maxdir=3; } x1=gp[0].x;x2=n; y1=gp[0].y;y2=m; maxn=cout1(); if(maxn>gp[k].max) { gp[k].max=maxn; gp[k].maxdir=4; } } sort(gp,gp+gn,cmp); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { initial(); updata(); while(sum) { ans++; if(sum==gp[0].max)break; chang(); updata(); } cout<<ans<<endl; } return 0; }