狗狗40题~(Volume A)

A - The Willy Memorial Program

大模拟题……

一开始的思路不对,修修补补WA了十发。当时想直接一个并查集做连通来搞定它,结果发现不能很好地判断各管的水位。究其原因还是因为这个是跟进水的过程顺序有关的。

所以最后AC的思路还是按模拟来做,在已经连通的管子中找最低的link连出去,不断更新水位,合并管子。

有些细节注意一下,AC~

 

  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <cmath>
  6            
  7 using namespace std;
  8 #define lson o<<1
  9 #define rson o<<1|1
 10 #define max(a,b) ((a)>(b)?(a):(b))
 11 #define min(a,b) ((a)<(b)?(a):(b))
 12 #define INF 200000000
 13            
 14 typedef long long ll;
 15 int p,lk;     
 16 struct pipe{
 17    int bot,top,lp;
 18 }pp[30];
 19 struct link{
 20    int u,v,h;
 21 }ln[60];
 22 int fa[30],vis[60],hs[30],visp[30];
 23 int cmp(struct link a,struct link b){
 24    return a.h>b.h;
 25 }
 26 void init(){
 27    for(int i=1;i<=p;i++)fa[i]=i;
 28 }
 29 int finds(int x){
 30    return fa[x]!=x?fa[x]=finds(fa[x]):x;
 31 }
 32 void unions(int u,int v){
 33    int fu=finds(u),fv=finds(v);
 34    if(fu!=fv)fa[fu]=fv;
 35 }
 36 int main(){
 37 //("a.in","r",stdin);freopen("a.out","w",stdout);
 38      int t;
 39      scanf("%d",&t);
 40      while(t--){
 41         memset(vis,0,sizeof vis);
 42         memset(visp,0,sizeof visp);
 43         scanf("%d",&p);
 44         int left,up,hi;
 45         for(int i=1;i<=p;i++){
 46             scanf("%d%d%d",&left,&up,&hi);
 47             pp[i].lp=left;pp[i].top=up;
 48             pp[i].bot=up+hi;
 49         }
 50         scanf("%d",&lk);
 51         for(int i=1;i<=lk;i++){
 52             scanf("%d%d%d",&left,&ln[i].h,&hi);
 53             for(int j=1;j<=p;j++)if(pp[j].bot>=ln[i].h&&pp[j].top<=ln[i].h){
 54                if(pp[j].lp+1==left)ln[i].u=j;
 55                if(pp[j].lp==left+hi)ln[i].v=j;
 56             }
 57         }
 58         sort(ln+1,ln+lk+1,cmp);
 59         int now=1,y=0,tar,h0,find=0,flag;
 60         scanf("%d%d",&tar,&h0);
 61         if(h0>pp[tar].bot||h0<=pp[tar].top){
 62             printf("No Solution\n");
 63             continue;
 64         }
 65         for(int i=1;i<=p;i++)hs[i]=pp[i].bot;
 66         while(!find){
 67            visp[now]=1;
 68            if(now==tar)find=1;
 69            if(find){
 70               flag=1;
 71               init();
 72               for(int i=1;i<=lk&&ln[i].h>=h0;i++)unions(ln[i].u,ln[i].v);
 73               for(int i=1;i<=p;i++)if(finds(i)==finds(tar)){
 74                    if(h0<=pp[i].top)flag=0;
 75                    hs[i]=min(hs[i],h0);
 76               }
 77            }else{
 78               flag=0;
 79               int pos;
 80               for(pos=1;pos<=lk;pos++)if(!vis[pos])
 81                 if(visp[ln[pos].u]^visp[ln[pos].v]){flag=1;break;}
 82               if(!flag)break;
 83               now=visp[ln[pos].u]?ln[pos].u:ln[pos].v;
 84               y=ln[pos].h;
 85               vis[pos]=1;
 86               init();
 87               for(int i=1;i<=lk&&ln[i].h>y;i++)unions(ln[i].u,ln[i].v);
 88               for(int i=1;i<=p;i++)if(finds(i)==finds(now))hs[i]=min(hs[i],y);
 89               now=visp[ln[pos].v]?ln[pos].u:ln[pos].v;
 90            }
 91         }
 92         for(int i=1;i<=p;i++)if(hs[i]<pp[i].top){flag=0;break;}
 93         if(!flag){
 94            printf("No Solution\n");
 95            continue;
 96         }
 97         int ans=0;
 98         for(int i=1;i<=p;i++)ans+=pp[i].bot-hs[i];
 99         printf("%d\n",ans);
100      }
101      return 0;
102 }
View Code

 

B - Farmland

这题有很多要学习的地方,利用题目条件,在多边形内部的点必然和某顶点连了边,这样如果每次都找逆时针转最靠近的边,找到的闭合图形内部就一定没有其它点了。

但这么做有一个条件,那就是一定要确保闭合,就是搜到有一个遍历过的点了还不行,下一个点也必须是遍历过的点

第二是判重的问题,一条边允许搜正反两次,那么有的(不是所有)多边形可能就走了正逆时针2次,怎么判断呢?

有的人用面积法,按照遍历的方式,应该舍去面积为正的。

最简单的办法是加一个点,在最左下的点上连一条边到(-1001,-1001),保证如果逆时针走一定会在某个点上走出来,达不到闭合的条件。

 

  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <vector>
  7            
  8 using namespace std;
  9 #define lson o<<1
 10 #define rson o<<1|1
 11 #define max(a,b) (a)>(b)?(a):(b)
 12 #define min(a,b) (a)<(b)?(a):(b)
 13 #define INF 2000000000
 14 #define eps 1e-6
 15            
 16 typedef long long ll;
 17 const double pi=acos(-1);
 18 bool vis[210][210],visp[210];
 19 struct point{
 20    int x,y;
 21    point(){}
 22    point(int x,int y):x(x),y(y){}
 23    point operator - (point a){return point(x-a.x,y-a.y);}
 24    point operator + (point a){return point(x+a.x,y+a.y);}
 25    bool operator == (point a){return x==a.x&&y==a.y;}
 26 }p[210];
 27 int tx,ty;   
 28 int dcmp(double x){
 29    if(x>eps)return 1;
 30    if(x<-eps)return -1;
 31    return 0;
 32 }        
 33 int cross(point a,point b){
 34    return a.x*b.y-a.y*b.x;
 35 }
 36 int dot(point a,point b){
 37    return a.x*b.x+a.y*b.y;
 38 }
 39 double length(point a){
 40    return sqrt(dot(a,a));       
 41 }
 42 bool cmp(const int& a,const int&b){
 43    double a1=atan2(p[a].y-ty,p[a].x-tx);
 44    double a2=atan2(p[b].y-ty,p[b].x-tx);
 45    return a1<a2;
 46 }
 47 bool InPoly(vector <point> poly,point p0){
 48    int n=poly.size();
 49    int cn=0;
 50    for(int i=0;i<n;i++){
 51       int j=(i+1)%n;
 52       if(poly[i]==p0||poly[j]==p0)return false;
 53       int d1=poly[i].y-p0.y,d2=poly[j].y-p0.y;
 54       int c=cross(poly[j]-poly[i],p0-poly[i]);
 55       if(c==0 && dot(poly[i]-p0,poly[j]-p0)<0)return 1;
 56       else if(c==0)return 0; 
 57       if(c>0 && d1<0 && d2>=0)cn++;
 58       if(c<0 && d1>=0 && d2<0)cn--;
 59    }
 60    return cn;
 61 }
 62 double area(vector <point> poly){
 63    int n=poly.size();
 64    double a=0;
 65    for(int i=0;i<n;i++)a+=cross(poly[i],poly[(i+1)%n]);
 66    return a;
 67 }
 68 vector <int> g[210];
 69 vector <point> poly;
 70 vector <int> tp;
 71 
 72 int main(){
 73    //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
 74    int t;
 75    scanf("%d",&t);
 76    while(t--){
 77       int n,k,m,ans=0;
 78       memset(vis,0,sizeof vis);
 79       scanf("%d",&n);
 80       for(int i=0;i<=n;i++)g[i].clear();
 81       for(int i=1;i<=n;i++){
 82          int u,v;
 83          scanf("%d",&u);
 84          scanf("%d%d%d",&p[u].x,&p[u].y,&m);
 85          while(m--){
 86            scanf("%d",&v);
 87            g[u].push_back(v);
 88          }
 89       }
 90       scanf("%d",&k);
 91       for(int i=1;i<=n;i++){
 92          tx=p[i].x;ty=p[i].y;
 93          sort(g[i].begin(),g[i].end(),cmp);
 94       }
 95       for(int i=1;i<=n;i++)
 96        for(int u=0,j=g[i][u];u<g[i].size();u++,j=g[i][u])if(!vis[i][j]){
 97           vis[i][j]=1;
 98           tp.clear();
 99           tp.push_back(i);
100           tp.push_back(j);
101           bool flag=true;
102           memset(visp,0,sizeof visp);
103           visp[i]=visp[j]=true;
104           while(flag){
105              flag=1;
106              int now=tp[tp.size()-1];
107              int sec=tp[tp.size()-2];
108              if(g[now].size()==1){flag=0;break;}
109              int e;
110              for(e=0;e<g[now].size();e++)if(g[now][e]==sec)break;
111              int x=g[now][(e+1)%g[now].size()];
112              if(vis[now][x]){flag=false;break;}
113              vis[now][x]=1;
114              tp.push_back(x);
115              if(visp[x])break;
116              visp[x]=true;
117           }
118           if(!flag)continue;
119           poly.clear();
120           int last=tp[tp.size()-1];
121           int pos;
122           for(pos=tp.size()-2;pos>=0;pos--){
123              poly.push_back(p[tp[pos]]);
124              //printf("%d ",tp[pos]);
125              if(last==tp[pos])break;
126           }
127           //printf("polygon = %d\n",poly.size());
128           if(poly.size()==k){
129              flag=true;
130              for(int u=1;u<=n;u++)if(InPoly(poly,p[u]))
131                {flag=false;break;}
132              if(flag && dcmp(area(poly))>0)ans++;
133           }
134        }
135        printf("%d\n",ans);
136    }
137    return 0;
138 }
View Code

 

 

 

C - Transmitters

 

必须有一个点在直径上,所有直接暴力。

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5            
 6 using namespace std;
 7 #define lson o<<1
 8 #define rson o<<1|1
 9 #define max(a,b) (a)>(b)?(a):(b)
10 #define min(a,b) (a)<(b)?(a):(b)
11 #define INF 200000000
12            
13 typedef long long ll;
14 int n,x0,y0,x[200],y[200];
15 double r;
16 int cal_above(double k){
17    int i,cnt=0;
18    for(i=0;i<n;i++)
19      if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r && y[i]>=y0+k*(x[i]-x0))
20        cnt++;
21    return cnt;
22 }  
23 int cal_below(double k){
24    int i,cnt=0;
25    for(i=0;i<n;i++)
26      if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r && y[i]<=y0+k*(x[i]-x0))
27        cnt++;
28    return cnt;
29 }       
30 int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
31    while(scanf("%d%d%lf",&x0,&y0,&r) && r>0){
32      int i,ans=0;
33      scanf("%d",&n);
34      for(i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]);
35      double k;
36      for(i=0;i<n;i++)if(x[i]!=x0){
37        k=(double)(y[i]-y0)/(x[i]-x0);
38        ans=max(ans,cal_above(k));
39        ans=max(ans,cal_below(k));
40      }
41      int c1=0,c2=0;
42      for(i=0;i<n;i++)if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r){
43        if(x[i]<=x0)c1++;
44        if(x[i]>=x0)c2++;
45      }
46      ans=max(ans,c1);ans=max(ans,c2);
47      printf("%d\n",ans);
48    }
49    return 0;
50 }
View Code

 

H - Mondriaan's Dream

 

一个经典的状压dp,需要用dfs搜索当前行的填充方案,填满后按下一行的填充状态dp

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cmath>
 6            
 7 using namespace std;
 8 #define lson o<<1
 9 #define rson o<<1|1
10 #define max(a,b) (a)>(b)?(a):(b)
11 #define min(a,b) (a)<(b)?(a):(b)
12 #define INF 200000000
13            
14 typedef long long ll;
15 int h,w;
16 ll dp[20][1<<13];
17 void dfs(int sta,int cur,int ori,int beg){
18    dp[cur+1][sta]+=dp[cur][ori];
19    int bas=3<<beg;
20    for(int i=beg;i<=w-2;i++){
21       if((sta&bas)==0)
22             dfs(sta|bas,cur,ori,i+1);
23       bas<<=1;
24    }
25 }           
26 int main(){
27    
28    while(scanf("%d%d",&h,&w) && w){
29      int i,j,FULL=(1<<w)-1;
30      memset(dp,0,sizeof dp);
31      dp[0][FULL]=1;
32      for(i=0;i<h;i++)
33        for(j=0;j<(1<<w);j++){
34            dfs(FULL^j,i,j,0);
35        }
36      printf("%lld\n",dp[h][FULL]);
37    }
38    return 0;
39 }
View Code

 

F - Space Station Shielding

 

因为这题知道了有一个小算法叫做 FloodFill ,简单来说就是bfs,从外面的点搜索所有可以reach的点,然后把周围如果和格子接触就染色。

这就相当于把所有在表面的面染色了。

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cmath>
 6            
 7 using namespace std;
 8 #define lson o<<1
 9 #define rson o<<1|1
10 #define max(a,b) (a)>(b)?(a):(b)
11 #define min(a,b) (a)<(b)?(a):(b)
12 #define INF 200000000
13            
14 typedef long long ll;
15 int vis[80][80][80],g[80][80][80];
16 int ans,n,m,k,l;
17 int dx[6]={1,-1,0,0,0,0},dy[6]={0,0,1,-1,0,0},dz[6]={0,0,0,0,1,-1};
18 void bfs(int now){
19    int q[80*80*80],from=0,to=0;
20    q[to++]=now;
21    int vx,vy,vz,d,ux,uy,uz;
22    while(from<to){
23        vx=q[from]%n;
24        vy=(q[from]%(m*n))/n;
25        vz=q[from]/(m*n);
26        from++;
27        for(d=0;d<6;d++){
28          ux=vx+dx[d];
29          uy=vy+dy[d];
30          uz=vz+dz[d];
31          if(ux>=0&&ux<n && uy>=0&&uy<m && uz>=0&&uz<k && !vis[ux][uy][uz]){
32            if(g[ux][uy][uz])ans++;
33            else{
34                q[to++]=uz*m*n+uy*n+ux;
35                vis[ux][uy][uz]=1;
36            }
37          }
38        }            
39    }
40 }          
41 int main(){
42 //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
43    while(scanf("%d%d%d%d",&n,&m,&k,&l) && n){
44       memset(vis,0,sizeof vis);
45       memset(g,0,sizeof g);
46       int pos,x,y,z;
47       while(l--){
48          scanf("%d",&pos);
49           x=pos%n+1;
50           y=(pos%(m*n))/n+1;
51           z=pos/(m*n)+1;
52           g[x][y][z]=1;
53       }
54       n+=2;m+=2;k+=2;
55       ans=0;
56       int i,j;
57       for(i=0;i<m;i++)
58         for(j=0;j<k;j++)if(!vis[0][i][j])bfs(j*m*n+i*n+0);
59       for(i=0;i<m;i++)
60         for(j=0;j<k;j++)if(!vis[n-1][i][j])bfs(j*m*n+i*n+n-1);
61       for(i=0;i<n;i++)
62         for(j=0;j<k;j++)if(!vis[i][0][j])bfs(j*m*n+i);
63       for(i=0;i<n;i++)
64         for(j=0;j<k;j++)if(!vis[i][m-1][j])bfs(j*m*n+(m-1)*n+i);
65       for(i=0;i<n;i++)
66         for(j=0;j<m;j++)if(!vis[i][j][0])bfs(j*n+i);
67       for(i=0;i<n;i++)
68         for(j=0;j<m;j++)if(!vis[i][j][k-1])bfs(j*n+i+(k-1)*m*n);
69       printf("The number of faces needing shielding is %d.\n",ans);
70    }
71    return 0;
72 }
View Code

 

 

I - Hike on a Graph

bfs搜索~

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cmath>
 6            
 7 using namespace std;
 8 #define lson o<<1
 9 #define rson o<<1|1
10 #define max(a,b) (a)>(b)?(a):(b)
11 #define min(a,b) (a)<(b)?(a):(b)
12 #define INF 200000000
13 #define N 51           
14 typedef long long ll;
15 int g[60][60],vis[60][60][60],d[60][60][60];     
16 int n,ans;  
17 void bfs(int px,int py,int pz){
18     int q[60*60*60];
19     int from=0,to=0,ux,uy,uz;
20     q[to++]=px*N*N+py*N+pz;
21     while(from<to){
22        ux=q[from]/(N*N);
23        uy=(q[from]%(N*N))/N;
24        uz=q[from]%N;
25        vis[ux][uy][uz]=1;
26        if(ux==uy&&uy==uz){ans=d[ux][uy][uz];return;}
27        from++;
28        int i;
29        for(i=1;i<=n;i++)if(g[ux][i]==g[uy][uz]&&!vis[i][uy][uz]){
30            d[i][uy][uz]=min(d[i][uy][uz]>=0?d[i][uy][uz]:INF,1+d[ux][uy][uz]);
31            q[to++]=i*N*N+uy*N+uz;
32        }
33        for(i=1;i<=n;i++)if(g[uy][i]==g[uz][ux]&&!vis[ux][i][uz]){
34            d[ux][i][uz]=min(d[ux][i][uz]>=0?d[ux][i][uz]:INF,1+d[ux][uy][uz]);
35            q[to++]=ux*N*N+i*N+uz;
36        }
37        for(i=1;i<=n;i++)if(g[uz][i]==g[ux][uy]&&!vis[ux][uy][i]){
38            d[ux][uy][i]=min(d[ux][uy][i]>=0?d[ux][uy][i]:INF,1+d[ux][uy][uz]);
39            q[to++]=ux*N*N+uy*N+i;
40        }
41     }
42 }
43 int main(){
44 //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
45    int p1,p2,p3;
46    while(scanf("%d",&n) && n){
47        scanf("%d%d%d",&p1,&p2,&p3);
48        memset(vis,0,sizeof vis);
49        memset(d,-1,sizeof d);
50        memset(g,0,sizeof g);
51        int i,j;
52        char s[5];
53        for(i=1;i<=n;i++)
54          for(j=1;j<=n;j++){
55            scanf("%s",s);
56            g[i][j]=s[0]-'a'+1;
57          }
58        ans=-1;
59        d[p1][p2][p3]=0;
60        bfs(p1,p2,p3);
61        if(ans>=0)printf("%d\n",ans);
62        else printf("impossible\n");
63    }
64    return 0;
65 }
View Code

 


G - Square Ice

 

模拟~我的做法是把逐个把0的状态定下来然后print

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <cmath>
 6            
 7 using namespace std;
 8 #define lson o<<1
 9 #define rson o<<1|1
10 #define max(a,b) (a)>(b)?(a):(b)
11 #define min(a,b) (a)<(b)?(a):(b)
12 #define INF 200000000
13 
14 typedef long long ll;
15 int g[30][30];
16 char sq[100][100];           
17 int main(){
18 //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
19    int m,t=1;
20    while(scanf("%d",&m) && m){
21       int i,j;
22       memset(sq,0,sizeof sq);
23       memset(g,0,sizeof g);
24       for(i=0;i<m;i++)
25         for(j=0;j<m;j++)scanf("%d",&g[i][j]);
26       for(i=0;i<m;i++)
27         for(j=0;j<m;j++)if(!g[i][j]){
28            if(i && (g[i-1][j]==1||g[i-1][j]==6||g[i-1][j]==4))g[i][j]+=4;
29            if(!j || (g[i][j-1]==6||g[i][j-1]==2||g[i][j-1]==-1))g[i][j]+=2;
30         }
31       int px,py;;
32       for(i=0;i<m;i++)
33         for(j=0;j<m;j++){
34            px=i*4;py=j*4+2;
35            sq[px][py]='O';
36            if(g[i][j]==6||g[i][j]==4||g[i][j]==-1){sq[px-1][py]='|';sq[px-2][py]='H';}
37            if(g[i][j]==2||g[i][j]==0||g[i][j]==-1){sq[px+1][py]='|';sq[px+2][py]='H';}
38            if(g[i][j]==6||g[i][j]==2||g[i][j]==1){sq[px][py-1]='-';sq[px][py-2]='H';}
39            if(g[i][j]==4||g[i][j]==0||g[i][j]==1){sq[px][py+1]='-';sq[px][py+2]='H';}
40         }
41       
42       if(t>1)printf("\n");
43       printf("Case %d:\n\n",t);
44       for(i=0;i<4*m+3;i++)printf("*");
45       printf("\n");
46       for(i=0;i<=4*m-4;i++){
47         printf("*");
48         for(j=0;j<=4*m;j++){
49            if(!sq[i][j])printf(" ");
50            else printf("%c",sq[i][j]);
51         }
52         printf("*\n");
53       }
54       for(i=0;i<4*m+3;i++)printf("*");
55       printf("\n");
56       
57       t++;
58    }
59    return 0;
60 }
View Code

 

D - Split Windows

看起来很神烦,其实还好,代码很简洁

 

  1 #include <stdio.h>
  2 #include <cmath>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 typedef pair<int,int>  pii;
  9 struct node{
 10     char v;
 11     int h,w;
 12     int left,right;
 13 }tr[100];
 14 char buf[10000],map[500][500];
 15 int sz;
 16 char* build(int now,char *s){
 17    char *p=s;
 18    if(*p==0)return p;
 19    tr[now].v=*p;
 20    if(*(p+1)){
 21       if(*p<='Z'&&*p>='A')return p+1;
 22       else{
 23          tr[now].left=++sz;tr[now].right=++sz;
 24          p=build(tr[now].left,p+1);
 25          p=build(tr[now].right,p);
 26          return p;
 27       }
 28    }
 29 }
 30 void dfs(int now){
 31    if(tr[now].v!='|'&&tr[now].v!='-')tr[now].w=tr[now].h=2;
 32    else{
 33       dfs(tr[now].left);dfs(tr[now].right);
 34       if(tr[now].v=='|'){
 35          tr[now].w=tr[tr[now].left].w+tr[tr[now].right].w;
 36          tr[now].h=max(tr[tr[now].left].h,tr[tr[now].right].h);
 37       }else{
 38          tr[now].h=tr[tr[now].left].h+tr[tr[now].right].h;
 39          tr[now].w=max(tr[tr[now].left].w,tr[tr[now].right].w);
 40       }
 41    }
 42 }
 43 void cal(int now,int w,int h){
 44    tr[now].w=w;tr[now].h=h;
 45    if(tr[now].v<='Z'&&tr[now].v>='A')return;
 46    
 47    if(tr[now].v=='-'){
 48       int down=tr[now].h*tr[tr[now].right].h/(tr[tr[now].left].h+tr[tr[now].right].h);
 49       cal(tr[now].left,tr[now].w,tr[now].h-down);
 50       cal(tr[now].right,tr[now].w,down);
 51    }
 52    else if(tr[now].v=='|'){
 53       int down=tr[now].w*tr[tr[now].right].w/(tr[tr[now].left].w+tr[tr[now].right].w);
 54       cal(tr[now].left,tr[now].w-down,tr[now].h);
 55       cal(tr[now].right,down,tr[now].h);
 56    }
 57 }
 58 void make_map(int now,int x,int y){
 59    if(tr[now].v!='|'&&tr[now].v!='-'){
 60          map[x][y]=tr[now].v;
 61          int w=tr[now].w,h=tr[now].h;
 62          for(int i=x+1;i<x+h;i++)if(!map[i][y])map[i][y]='|';
 63          if(!(map[x+h][y]<='Z'&&map[x+h][y]>='A'))map[x+h][y]='*';
 64          for(int i=x+1;i<x+h;i++)if(!map[i][y+w])map[i][y+w]='|';
 65          if(!(map[x+h][y+w]<='Z'&&map[x+h][y+w]>='A'))map[x+h][y+w]='*';
 66          if(!(map[x][y+w]<='Z'&&map[x][y+w]>='A'))map[x][y+w]='*';
 67          for(int i=y+1;i<y+w;i++)if(!map[x][i])map[x][i]='-';
 68          for(int i=y+1;i<y+w;i++)if(!map[x+h][i])map[x+h][i]='-';
 69    }
 70    else if(tr[now].v=='-'){
 71       make_map(tr[now].left,x,y);
 72       make_map(tr[now].right,x+tr[tr[now].left].h,y);
 73    }
 74    else{
 75       make_map(tr[now].left,x,y);
 76       make_map(tr[now].right,x,y+tr[tr[now].left].w);
 77    }
 78 }
 79 int main(){
 80     //freopen("r.in","r",stdin);freopen("r.out","w",stdout);
 81    int t,cs=1;
 82    scanf("%d",&t);
 83    while(t--){
 84       scanf("%s",buf);
 85       sz=0;
 86       memset(map,0,sizeof map);
 87       build(sz,buf);
 88       dfs(0);
 89       cal(0,tr[0].w,tr[0].h);
 90       make_map(0,0,0);
 91       printf("%d\n",cs++);
 92       for(int i=0;i<=tr[0].h;i++){
 93         for(int j=0;j<=tr[0].w;j++){
 94             if(map[i][j])printf("%c",map[i][j]);
 95             else printf(" ");
 96         }
 97         printf("\n");
 98       }
 99    }
100    return 0;
101 }
View Code

 

 

 

E - Sorting It All Out

 

拓扑排序

 

 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 #include <stack>
 6            
 7 using namespace std;
 8 #define lson o<<1
 9 #define rson o<<1|1
10 #define max(a,b) (a)>(b)?(a):(b)
11 #define min(a,b) (a)<(b)?(a):(b)
12 #define INF 200000000
13            
14 typedef long long ll;
15 int first[30],next[30*30],to[30*30],inc[30],g[30][30];  
16 int n,m,edge;
17 int q[30],res;
18 int toposort(){
19     stack <int> s;
20     int i,du[30];
21     for(i=0;i<30;i++)du[i]=inc[i];
22     res=0;
23     for(i=1;i<=n;i++)if(!du[i])
24       s.push(i);
25     int u,e,v;
26     while(!s.empty()){
27        u=s.top();s.pop();
28        q[res++]=u;
29        e=first[u];
30        while(e!=-1){
31          du[to[e]]--;
32          if(!du[to[e]])s.push(to[e]);
33          e=next[e];
34        }
35     }
36     if(res<n)return -1;
37     for(i=0;i<n-1;i++)if(!g[q[i]][q[i+1]])return 0;
38     return 1;
39 }
40 int main(){
41 //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
42    char str[10];
43    while(scanf("%d%d",&n,&m) && n){
44        int u,v,flag=0;
45        memset(first,-1,sizeof first);
46        memset(next,-1,sizeof next);
47        memset(inc,0,sizeof inc);
48        memset(g,0,sizeof g);
49        edge=1;
50        for(int i=1;i<=m;i++){
51          scanf("%s",str);
52          if(flag)continue;
53          u=str[0]-'A'+1;
54          v=str[2]-'A'+1;
55          next[edge]=first[u];
56          first[u]=edge;to[edge++]=v;
57          inc[v]++;
58          g[u][v]=1;
59          res=0;
60          flag=toposort();
61          if(flag==1){
62             printf("Sorted sequence determined after %d relations: ",i);
63             for(int j=0;j<n;j++)printf("%c",'A'+q[j]-1);
64             printf(".\n");
65          }else if(flag==-1){
66                printf("Inconsistency found after %d relations.\n",i);
67          }
68        }
69        if(!flag)printf("Sorted sequence cannot be determined.\n");
70    }
71    return 0;
72 }
View Code

 


J - A Well-Formed Problem

 

这个是不是可以叫做蘑菇题了= =

一开始觉得hash,不过还是太麻烦改成了set……

模拟题实现起来也有很多可以学习的。做完看了一下watashi的代码觉得简直简洁啊!

 

  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <cmath>
  6 #include <stack>
  7 #include <set>
  8 #include <string>
  9 #include <cctype>
 10            
 11 using namespace std;
 12 #define lson o<<1
 13 #define rson o<<1|1
 14 #define max(a,b) (a)>(b)?(a):(b)
 15 #define min(a,b) (a)<(b)?(a):(b)
 16 #define INF 200000000
 17 #define STACK_CLEAR while(!ele.empty())ele.pop();
 18 #define SKIP(p) for(;*p==' ';p++);
 19 #define GET(p)  for(;isalnum(*p)||*p=='-';p++);
 20 #define EAT(p) while(*p!='"'&&*p!='\0')p++;
 21            
 22 typedef long long ll;
 23 stack <string> ele;
 24 set <string> st;
 25 set <string> attr;
 26 const char START[]= "<?xml version=\"1.0\"?>" ;
 27 const char END[]="<?end?>";
 28 int root;
 29 char* addnew(char* s){
 30       int shan=0;
 31       char *p=s+1;
 32       
 33       SKIP(p);
 34       if(*p=='/')++p,shan=1;
 35       attr.clear();
 36       
 37       SKIP(p);
 38       char *t0=p;
 39       GET(p);
 40       string t=string(t0,p);
 41       SKIP(p);
 42       
 43       while(*p!='>'&&*p!='/'&&*p){
 44             char *s0=p;
 45             GET(p);
 46             string ar=string(s0,p);
 47             /*for(;s0<p;s0++)printf("%c",*s0);
 48             printf("\n");*/
 49             
 50             if(attr.count(ar)>0)return NULL;
 51             attr.insert(ar);
 52             SKIP(p);
 53             if(*p!='=')return NULL;
 54             ++p;SKIP(p);
 55             if(*p!='"')return NULL;
 56             ++p;EAT(p);
 57             if(*p=='\0')return NULL;
 58             ++p;SKIP(p);
 59       }
 60       
 61       if(shan){
 62          if(ele.empty()||ele.top()!=t)return NULL;
 63          ele.pop();
 64          st.erase(t);
 65       }else if(*p=='/'){
 66             if(ele.empty())root++;
 67             ++p;SKIP(p);
 68       }
 69       else{
 70          if(st.count(t)>0)return NULL;
 71          if(ele.empty())root++;
 72          ele.push(t);
 73          st.insert(t);
 74       }
 75       if(*p!='>')return NULL;
 76       return p;
 77    }
 78 int feed(char *p){
 79    char *s=p;
 80    while(*s){
 81       if(*s=='<'){
 82          s=addnew(s);
 83          if(s==NULL)return 0;
 84       }
 85       else s++;
 86    }
 87    return 1;
 88 }
 89 int main(){
 90    //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
 91    char s[10010];
 92    gets(s);
 93    int flag=1;
 94    while(strcmp(s,END)){
 95       STACK_CLEAR;
 96       st.clear();
 97       gets(s);
 98       flag=1;
 99       root=0;
100       while(strcmp(s,START)&&strcmp(s,END)){
101          if(!flag||feed(s)==0)flag=0;
102          gets(s);
103       }
104       if(!flag||root!=1||!ele.empty())printf("non well-formed\n");
105        else printf("well-formed\n");
106    }
107    
108    return 0;
109 }
View Code

 


 



 

posted @ 2014-08-09 10:46  Ixia  阅读(273)  评论(0编辑  收藏  举报