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 }
View Code

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
",cas++,solve());
122     }
123     return 0;
124 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/4945043.html