狗狗40题~ (Volume A)

来源:互联网 发布:emui 知乎 编辑:程序博客网 时间:2024/05/18 02:21

A - The Willy Memorial Program

大模拟题……

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

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

有些细节注意一下,AC~

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))#define INF 200000000           typedef long long ll;int p,lk;     struct pipe{   int bot,top,lp;}pp[30];struct link{   int u,v,h;}ln[60];int fa[30],vis[60],hs[30],visp[30];int cmp(struct link a,struct link b){   return a.h>b.h;}void init(){   for(int i=1;i<=p;i++)fa[i]=i;}int finds(int x){   return fa[x]!=x?fa[x]=finds(fa[x]):x;}void unions(int u,int v){   int fu=finds(u),fv=finds(v);   if(fu!=fv)fa[fu]=fv;}int main(){//("a.in","r",stdin);freopen("a.out","w",stdout);     int t;     scanf("%d",&t);     while(t--){        memset(vis,0,sizeof vis);        memset(visp,0,sizeof visp);        scanf("%d",&p);        int left,up,hi;        for(int i=1;i<=p;i++){            scanf("%d%d%d",&left,&up,&hi);            pp[i].lp=left;pp[i].top=up;            pp[i].bot=up+hi;        }        scanf("%d",&lk);        for(int i=1;i<=lk;i++){            scanf("%d%d%d",&left,&ln[i].h,&hi);            for(int j=1;j<=p;j++)if(pp[j].bot>=ln[i].h&&pp[j].top<=ln[i].h){               if(pp[j].lp+1==left)ln[i].u=j;               if(pp[j].lp==left+hi)ln[i].v=j;            }        }        sort(ln+1,ln+lk+1,cmp);        int now=1,y=0,tar,h0,find=0,flag;        scanf("%d%d",&tar,&h0);        if(h0>pp[tar].bot||h0<=pp[tar].top){            printf("No Solution\n");            continue;        }        for(int i=1;i<=p;i++)hs[i]=pp[i].bot;        while(!find){           visp[now]=1;           if(now==tar)find=1;           if(find){              flag=1;              init();              for(int i=1;i<=lk&&ln[i].h>=h0;i++)unions(ln[i].u,ln[i].v);              for(int i=1;i<=p;i++)if(finds(i)==finds(tar)){                   if(h0<=pp[i].top)flag=0;                   hs[i]=min(hs[i],h0);              }           }else{              flag=0;              int pos;              for(pos=1;pos<=lk;pos++)if(!vis[pos])                if(visp[ln[pos].u]^visp[ln[pos].v]){flag=1;break;}              if(!flag)break;              now=visp[ln[pos].u]?ln[pos].u:ln[pos].v;              y=ln[pos].h;              vis[pos]=1;              init();              for(int i=1;i<=lk&&ln[i].h>y;i++)unions(ln[i].u,ln[i].v);              for(int i=1;i<=p;i++)if(finds(i)==finds(now))hs[i]=min(hs[i],y);              now=visp[ln[pos].v]?ln[pos].u:ln[pos].v;           }        }        for(int i=1;i<=p;i++)if(hs[i]<pp[i].top){flag=0;break;}        if(!flag){           printf("No Solution\n");           continue;        }        int ans=0;        for(int i=1;i<=p;i++)ans+=pp[i].bot-hs[i];        printf("%d\n",ans);     }     return 0;}

C - Transmitters

暴力不多说……(必须有一个点在直径上)

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000           typedef long long ll;int n,x0,y0,x[200],y[200];double r;int cal_above(double k){   int i,cnt=0;   for(i=0;i<n;i++)     if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r && y[i]>=y0+k*(x[i]-x0))       cnt++;   return cnt;}  int cal_below(double k){   int i,cnt=0;   for(i=0;i<n;i++)     if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r && y[i]<=y0+k*(x[i]-x0))       cnt++;   return cnt;}       int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);   while(scanf("%d%d%lf",&x0,&y0,&r) && r>0){     int i,ans=0;     scanf("%d",&n);     for(i=0;i<n;i++)scanf("%d%d",&x[i],&y[i]);     double k;     for(i=0;i<n;i++)if(x[i]!=x0){       k=(double)(y[i]-y0)/(x[i]-x0);       ans=max(ans,cal_above(k));       ans=max(ans,cal_below(k));     }     int c1=0,c2=0;     for(i=0;i<n;i++)if((x[i]-x0)*(x[i]-x0)+(y[i]-y0)*(y[i]-y0)<=r*r){       if(x[i]<=x0)c1++;       if(x[i]>=x0)c2++;     }     ans=max(ans,c1);ans=max(ans,c2);     printf("%d\n",ans);   }   return 0;}

H - Mondriaan's Dream

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

<span style="font-size:18px;">#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000           typedef long long ll;int h,w;ll dp[20][1<<13];void dfs(int sta,int cur,int ori,int beg){   dp[cur+1][sta]+=dp[cur][ori];   int bas=3<<beg;   for(int i=beg;i<=w-2;i++){      if((sta&bas)==0)            dfs(sta|bas,cur,ori,i+1);      bas<<=1;   }}           int main(){      while(scanf("%d%d",&h,&w) && w){     int i,j,FULL=(1<<w)-1;     memset(dp,0,sizeof dp);     dp[0][FULL]=1;     for(i=0;i<h;i++)       for(j=0;j<(1<<w);j++){           dfs(FULL^j,i,j,0);       }     printf("%lld\n",dp[h][FULL]);   }   return 0;}</span>

F - Space Station Shielding

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

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

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000           typedef long long ll;int vis[80][80][80],g[80][80][80];int ans,n,m,k,l;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};void bfs(int now){   int q[80*80*80],from=0,to=0;   q[to++]=now;   int vx,vy,vz,d,ux,uy,uz;   while(from<to){       vx=q[from]%n;       vy=(q[from]%(m*n))/n;       vz=q[from]/(m*n);       from++;       for(d=0;d<6;d++){         ux=vx+dx[d];         uy=vy+dy[d];         uz=vz+dz[d];         if(ux>=0&&ux<n && uy>=0&&uy<m && uz>=0&&uz<k && !vis[ux][uy][uz]){           if(g[ux][uy][uz])ans++;           else{               q[to++]=uz*m*n+uy*n+ux;               vis[ux][uy][uz]=1;           }         }       }               }}          int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);   while(scanf("%d%d%d%d",&n,&m,&k,&l) && n){      memset(vis,0,sizeof vis);      memset(g,0,sizeof g);      int pos,x,y,z;      while(l--){         scanf("%d",&pos);          x=pos%n+1;          y=(pos%(m*n))/n+1;          z=pos/(m*n)+1;          g[x][y][z]=1;      }      n+=2;m+=2;k+=2;      ans=0;      int i,j;      for(i=0;i<m;i++)        for(j=0;j<k;j++)if(!vis[0][i][j])bfs(j*m*n+i*n+0);      for(i=0;i<m;i++)        for(j=0;j<k;j++)if(!vis[n-1][i][j])bfs(j*m*n+i*n+n-1);      for(i=0;i<n;i++)        for(j=0;j<k;j++)if(!vis[i][0][j])bfs(j*m*n+i);      for(i=0;i<n;i++)        for(j=0;j<k;j++)if(!vis[i][m-1][j])bfs(j*m*n+(m-1)*n+i);      for(i=0;i<n;i++)        for(j=0;j<m;j++)if(!vis[i][j][0])bfs(j*n+i);      for(i=0;i<n;i++)        for(j=0;j<m;j++)if(!vis[i][j][k-1])bfs(j*n+i+(k-1)*m*n);      printf("The number of faces needing shielding is %d.\n",ans);   }   return 0;}

I - Hike on a Graph

bfs搜索~

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000#define N 51           typedef long long ll;int g[60][60],vis[60][60][60],d[60][60][60];     int n,ans;  void bfs(int px,int py,int pz){    int q[60*60*60];    int from=0,to=0,ux,uy,uz;    q[to++]=px*N*N+py*N+pz;    while(from<to){       ux=q[from]/(N*N);       uy=(q[from]%(N*N))/N;       uz=q[from]%N;       vis[ux][uy][uz]=1;       if(ux==uy&&uy==uz){ans=d[ux][uy][uz];return;}       from++;       int i;       for(i=1;i<=n;i++)if(g[ux][i]==g[uy][uz]&&!vis[i][uy][uz]){           d[i][uy][uz]=min(d[i][uy][uz]>=0?d[i][uy][uz]:INF,1+d[ux][uy][uz]);           q[to++]=i*N*N+uy*N+uz;       }       for(i=1;i<=n;i++)if(g[uy][i]==g[uz][ux]&&!vis[ux][i][uz]){           d[ux][i][uz]=min(d[ux][i][uz]>=0?d[ux][i][uz]:INF,1+d[ux][uy][uz]);           q[to++]=ux*N*N+i*N+uz;       }       for(i=1;i<=n;i++)if(g[uz][i]==g[ux][uy]&&!vis[ux][uy][i]){           d[ux][uy][i]=min(d[ux][uy][i]>=0?d[ux][uy][i]:INF,1+d[ux][uy][uz]);           q[to++]=ux*N*N+uy*N+i;       }    }}int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);   int p1,p2,p3;   while(scanf("%d",&n) && n){       scanf("%d%d%d",&p1,&p2,&p3);       memset(vis,0,sizeof vis);       memset(d,-1,sizeof d);       memset(g,0,sizeof g);       int i,j;       char s[5];       for(i=1;i<=n;i++)         for(j=1;j<=n;j++){           scanf("%s",s);           g[i][j]=s[0]-'a'+1;         }       ans=-1;       d[p1][p2][p3]=0;       bfs(p1,p2,p3);       if(ans>=0)printf("%d\n",ans);       else printf("impossible\n");   }   return 0;}

G - Square Ice

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

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000typedef long long ll;int g[30][30];char sq[100][100];           int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);   int m,t=1;   while(scanf("%d",&m) && m){      int i,j;      memset(sq,0,sizeof sq);      memset(g,0,sizeof g);      for(i=0;i<m;i++)        for(j=0;j<m;j++)scanf("%d",&g[i][j]);      for(i=0;i<m;i++)        for(j=0;j<m;j++)if(!g[i][j]){           if(i && (g[i-1][j]==1||g[i-1][j]==6||g[i-1][j]==4))g[i][j]+=4;           if(!j || (g[i][j-1]==6||g[i][j-1]==2||g[i][j-1]==-1))g[i][j]+=2;        }      int px,py;;      for(i=0;i<m;i++)        for(j=0;j<m;j++){           px=i*4;py=j*4+2;           sq[px][py]='O';           if(g[i][j]==6||g[i][j]==4||g[i][j]==-1){sq[px-1][py]='|';sq[px-2][py]='H';}           if(g[i][j]==2||g[i][j]==0||g[i][j]==-1){sq[px+1][py]='|';sq[px+2][py]='H';}           if(g[i][j]==6||g[i][j]==2||g[i][j]==1){sq[px][py-1]='-';sq[px][py-2]='H';}           if(g[i][j]==4||g[i][j]==0||g[i][j]==1){sq[px][py+1]='-';sq[px][py+2]='H';}        }            if(t>1)printf("\n");      printf("Case %d:\n\n",t);      for(i=0;i<4*m+3;i++)printf("*");      printf("\n");      for(i=0;i<=4*m-4;i++){        printf("*");        for(j=0;j<=4*m;j++){           if(!sq[i][j])printf(" ");           else printf("%c",sq[i][j]);        }        printf("*\n");      }      for(i=0;i<4*m+3;i++)printf("*");      printf("\n");            t++;   }   return 0;}

E - Sorting It All Out

拓扑排序

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <stack>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000           typedef long long ll;int first[30],next[30*30],to[30*30],inc[30],g[30][30];  int n,m,edge;int q[30],res;int toposort(){    stack <int> s;    int i,du[30];    for(i=0;i<30;i++)du[i]=inc[i];    res=0;    for(i=1;i<=n;i++)if(!du[i])      s.push(i);    int u,e,v;    while(!s.empty()){       u=s.top();s.pop();       q[res++]=u;       e=first[u];       while(e!=-1){         du[to[e]]--;         if(!du[to[e]])s.push(to[e]);         e=next[e];       }    }    if(res<n)return -1;    for(i=0;i<n-1;i++)if(!g[q[i]][q[i+1]])return 0;    return 1;}int main(){//freopen("a.in","r",stdin);freopen("a.out","w",stdout);   char str[10];   while(scanf("%d%d",&n,&m) && n){       int u,v,flag=0;       memset(first,-1,sizeof first);       memset(next,-1,sizeof next);       memset(inc,0,sizeof inc);       memset(g,0,sizeof g);       edge=1;       for(int i=1;i<=m;i++){         scanf("%s",str);         if(flag)continue;         u=str[0]-'A'+1;         v=str[2]-'A'+1;         next[edge]=first[u];         first[u]=edge;to[edge++]=v;         inc[v]++;         g[u][v]=1;         res=0;         flag=toposort();         if(flag==1){            printf("Sorted sequence determined after %d relations: ",i);            for(int j=0;j<n;j++)printf("%c",'A'+q[j]-1);            printf(".\n");         }else if(flag==-1){               printf("Inconsistency found after %d relations.\n",i);         }       }       if(!flag)printf("Sorted sequence cannot be determined.\n");   }   return 0;}

J - A Well-Formed Problem

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

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

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

#include <stdio.h>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>#include <stack>#include <set>#include <string>#include <cctype>           using namespace std;#define lson o<<1#define rson o<<1|1#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)#define INF 200000000#define STACK_CLEAR while(!ele.empty())ele.pop();#define SKIP(p) for(;*p==' ';p++);#define GET(p)  for(;isalnum(*p)||*p=='-';p++);#define EAT(p) while(*p!='"'&&*p!='\0')p++;           typedef long long ll;stack <string> ele;set <string> st;set <string> attr;const char START[]= "<?xml version=\"1.0\"?>" ;const char END[]="<?end?>";int root;char* addnew(char* s){      int shan=0;      char *p=s+1;            SKIP(p);      if(*p=='/')++p,shan=1;      attr.clear();            SKIP(p);      char *t0=p;      GET(p);      string t=string(t0,p);      SKIP(p);            while(*p!='>'&&*p!='/'&&*p){            char *s0=p;            GET(p);            string ar=string(s0,p);            /*for(;s0<p;s0++)printf("%c",*s0);            printf("\n");*/                        if(attr.count(ar)>0)return NULL;            attr.insert(ar);            SKIP(p);            if(*p!='=')return NULL;            ++p;SKIP(p);            if(*p!='"')return NULL;            ++p;EAT(p);            if(*p=='\0')return NULL;            ++p;SKIP(p);      }            if(shan){         if(ele.empty()||ele.top()!=t)return NULL;         ele.pop();         st.erase(t);      }else if(*p=='/'){            if(ele.empty())root++;            ++p;SKIP(p);      }      else{         if(st.count(t)>0)return NULL;         if(ele.empty())root++;         ele.push(t);         st.insert(t);      }      if(*p!='>')return NULL;      return p;   }int feed(char *p){   char *s=p;   while(*s){      if(*s=='<'){         s=addnew(s);         if(s==NULL)return 0;      }      else s++;   }   return 1;}int main(){   //freopen("a.in","r",stdin);freopen("a.out","w",stdout);   char s[10010];   gets(s);   int flag=1;   while(strcmp(s,END)){      STACK_CLEAR;      st.clear();      gets(s);      flag=1;      root=0;      while(strcmp(s,START)&&strcmp(s,END)){         if(!flag||feed(s)==0)flag=0;         gets(s);      }      if(!flag||root!=1||!ele.empty())printf("non well-formed\n");       else printf("well-formed\n");   }      return 0;}




0 0
原创粉丝点击