matrix_world_final_2011
C http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98613#problem/C
题意:输入16进制的n*m矩阵,其在二进制表示下有6种图中的哪几种。
解法:6种图黑点都是连通的,所以第一步先把黑的连通块标号,第二步6种图中白连通块的个数正好是0-5个,第二步每找到一个白块就找到它的边界,对应的黑块+1,最后每一个黑块中有多少白块就统计完了,按字典序输出即可。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<queue> 13 #include<stack> 14 #include<map> 15 #include<set> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=2e2+10; 23 char a[M][M]; 24 char str[8]="WAKJSD"; 25 bool black[M][M]; 26 int index_of_black; 27 int id[M][M]; 28 int dx[8]={0,0,1,-1}; 29 int dy[8]={1,-1,0,0}; 30 int n,m; 31 int sum[8]; 32 int count_of_black[M*M]; 33 int id_of_black; 34 vector<char> answer; 35 int to_int(char c){ 36 if(isdigit(c)) return c-'0'; 37 return c-'a'+10; 38 } 39 void init_black(){ 40 for(int i=0;i<n;i++){ 41 int len=0; 42 for(int j=0;j<m;j++){ 43 int value=to_int(a[i][j]); 44 for(int k=3;k>=0;k--){ 45 black[i][len++]=(value>>k)&1; 46 } 47 } 48 } 49 m<<=2; 50 } 51 void init_id(){ 52 for(int i=0;i<n;i++){ 53 for(int j=0;j<m;j++){ 54 id[i][j]=0; 55 } 56 } 57 } 58 void init_count_of_black(){ 59 for(int i=1;i<=index_of_black;i++){ 60 count_of_black[i]=0; 61 } 62 } 63 bool inside(int x,int y){ 64 return x>=0&&x<n&&y>=0&&y<m; 65 } 66 void dfs_black(int x,int y,int Index){ 67 id[x][y]=Index; 68 for(int i=0;i<4;i++){ 69 int tx=x+dx[i]; 70 int ty=y+dy[i]; 71 if(!inside(tx,ty)) continue; 72 if(!black[tx][ty]) continue; 73 if(id[tx][ty]) continue; 74 dfs_black(tx,ty,Index); 75 } 76 } 77 void solve_black(){ 78 index_of_black=0; 79 for(int i=0;i<n;i++){ 80 for(int j=0;j<m;j++){ 81 if(!black[i][j]) continue; 82 if(id[i][j]) continue; 83 dfs_black(i,j,++index_of_black); 84 } 85 } 86 } 87 void dfs_white(int x,int y){ 88 id[x][y]=-1; 89 for(int i=0;i<4;i++){ 90 int tx=x+dx[i]; 91 int ty=y+dy[i]; 92 if(!inside(tx,ty)){ 93 id_of_black=0; 94 continue; 95 } 96 if(id[tx][ty]){ 97 if(id[tx][ty]>0&&id_of_black==-1){ 98 id_of_black=id[tx][ty]; 99 } 100 continue; 101 } 102 dfs_white(tx,ty); 103 } 104 } 105 void solve_white(){ 106 for(int i=0;i<n;i++){ 107 for(int j=0;j<m;j++){ 108 if(id[i][j]) continue; 109 id_of_black=-1; 110 dfs_white(i,j); 111 if(id_of_black==0) continue; 112 count_of_black[id_of_black]++; 113 } 114 } 115 } 116 void solve(){ 117 init_black(); 118 init_id(); 119 solve_black(); 120 init_count_of_black(); 121 solve_white(); 122 mt(sum,0); 123 for(int i=1;i<=index_of_black;i++){ 124 sum[count_of_black[i]]++; 125 } 126 answer.clear(); 127 for(int i=0;i<6;i++){ 128 for(int j=0;j<sum[i];j++){ 129 answer.push_back(str[i]); 130 } 131 } 132 sort(answer.begin(),answer.end()); 133 } 134 int main(){ 135 #ifdef txtout 136 freopen("in.txt","r",stdin); 137 freopen("out.txt","w",stdout); 138 #endif 139 int cas=1; 140 while(~scanf("%d%d",&n,&m),n|m){ 141 for(int i=0;i<n;i++){ 142 scanf("%s",a[i]); 143 } 144 solve(); 145 printf("Case %d: ",cas++); 146 int len=answer.size(); 147 for(int i=0;i<len;i++){ 148 putchar(answer[i]); 149 } 150 puts(""); 151 } 152 return 0; 153 }
K http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98613#problem/K
题意:求最小的能让任意多边形垂直下落通过的间距。
解法:先做凸包,求凸包的宽度即是答案。
1 //#define debug 2 //#define txtout 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<cctype> 8 #include<ctime> 9 #include<iostream> 10 #include<algorithm> 11 #include<vector> 12 #include<queue> 13 #include<stack> 14 #include<map> 15 #include<set> 16 #define mt(a,b) memset(a,b,sizeof(a)) 17 using namespace std; 18 typedef long long LL; 19 const double eps=1e-8; 20 const double pi=acos(-1.0); 21 const int inf=0x3f3f3f3f; 22 const int M=1e2+10; 23 struct point { 24 double x,y; 25 } p[M],res[M]; 26 int n; 27 char buffer[M]; 28 class Convex_Hull { ///凸包 29 bool mult(point sp,point ep,point op) { ///>包括凸包边上的点,>=不包括。 30 return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y); 31 } 32 static bool cmp(const point &a,const point &b) { ///整数不需fabs,a.y==b.y。 33 return a.y<b.y||(fabs(a.y-b.y)<eps&&a.x<b.x); 34 } 35 public: 36 int Graham(int n,point p[],point res[]) { ///传入点的个数,点数组p[],凸包点存在res[],返回凸包点数. 37 sort(p,p+n,cmp); 38 if(n==0) return 0; 39 res[0]=p[0]; 40 if(n==1) return 1; 41 res[1]=p[1]; 42 if(n==2) return 2; 43 res[2]=p[2]; 44 int top=1; 45 for(int i=2; i<n; i++) { 46 while(top&&mult(p[i],res[top],res[top-1])) { 47 top--; 48 } 49 res[++top]=p[i]; 50 } 51 int len=top; 52 res[++top]=p[n-2]; 53 for(int i=n-3; i>=0; i--) { 54 while(top!=len&&mult(p[i],res[top],res[top-1])) { 55 top--; 56 } 57 res[++top]=p[i]; 58 } 59 return top; 60 } 61 } gx; 62 class Convex_Hull_Wide{///凸包的宽 63 double xmult(point p1,point p2,point p0) { ///计算向量叉积(P1-P0)x(P2-P0) 64 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 65 } 66 double Square(double x) { ///平方 67 return x*x; 68 } 69 double Distance(point a,point b) { ///平面两点距离 70 return sqrt(Square(a.x-b.x)+Square(a.y-b.y)); 71 } 72 double get(point a,point b,point c){ 73 return fabs(xmult(a,b,c)); 74 } 75 public: 76 double Rotate_Calipers_Wide(point p[],int n) {///传入凸包和点数 77 double result=-1; 78 for(int i=0,j=1; i<n; i++) { 79 while(get(p[j+1],p[i+1],p[i])>get(p[j],p[i+1],p[i])){ 80 j=(j+1)%n; 81 } 82 double temp=get(p[j],p[i+1],p[i])/Distance(p[i],p[i+1]); 83 if(result==-1){ 84 result=temp; 85 continue; 86 } 87 result=min(result,temp); 88 } 89 return result; 90 } 91 }ts; 92 void round_up(double &x){ 93 sprintf(buffer,"%.6f",x); 94 int len=strlen(buffer); 95 for(int i=0;i<len;i++){ 96 if(buffer[i]=='.'){ 97 if(buffer[i+3]!='0'){ 98 buffer[i+3]='9'; 99 } 100 break; 101 } 102 } 103 sscanf(buffer,"%lf",&x); 104 } 105 double solve() { 106 int len=gx.Graham(n,p,res); 107 double result=ts.Rotate_Calipers_Wide(res,len); 108 round_up(result); 109 return result; 110 } 111 int main() { 112 #ifdef txtout 113 freopen("in.txt","r",stdin); 114 freopen("out.txt","w",stdout); 115 #endif 116 int cas=1; 117 while(~scanf("%d",&n),n) { 118 for(int i=0; i<n; i++) { 119 scanf("%lf%lf",&p[i].x,&p[i].y); 120 } 121 printf("Case %d: %.2f\n",cas++,solve()); 122 } 123 return 0; 124 }
end