狗狗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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }