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[];
struct link{
int u,v,h;
}ln[];
int fa[],vis[],hs[],visp[];
int cmp(struct link a,struct link b){
return a.h>b.h;
}
void init(){
for(int i=;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,,sizeof vis);
memset(visp,,sizeof visp);
scanf("%d",&p);
int left,up,hi;
for(int i=;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=;i<=lk;i++){
scanf("%d%d%d",&left,&ln[i].h,&hi);
for(int j=;j<=p;j++)if(pp[j].bot>=ln[i].h&&pp[j].top<=ln[i].h){
if(pp[j].lp+==left)ln[i].u=j;
if(pp[j].lp==left+hi)ln[i].v=j;
}
}
sort(ln+,ln+lk+,cmp);
int now=,y=,tar,h0,find=,flag;
scanf("%d%d",&tar,&h0);
if(h0>pp[tar].bot||h0<=pp[tar].top){
printf("No Solution\n");
continue;
}
for(int i=;i<=p;i++)hs[i]=pp[i].bot;
while(!find){
visp[now]=;
if(now==tar)find=;
if(find){
flag=;
init();
for(int i=;i<=lk&&ln[i].h>=h0;i++)unions(ln[i].u,ln[i].v);
for(int i=;i<=p;i++)if(finds(i)==finds(tar)){
if(h0<=pp[i].top)flag=;
hs[i]=min(hs[i],h0);
}
}else{
flag=;
int pos;
for(pos=;pos<=lk;pos++)if(!vis[pos])
if(visp[ln[pos].u]^visp[ln[pos].v]){flag=;break;}
if(!flag)break;
now=visp[ln[pos].u]?ln[pos].u:ln[pos].v;
y=ln[pos].h;
vis[pos]=;
init();
for(int i=;i<=lk&&ln[i].h>y;i++)unions(ln[i].u,ln[i].v);
for(int i=;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=;i<=p;i++)if(hs[i]<pp[i].top){flag=;break;}
if(!flag){
printf("No Solution\n");
continue;
}
int ans=;
for(int i=;i<=p;i++)ans+=pp[i].bot-hs[i];
printf("%d\n",ans);
}
return ;
}

B - Farmland

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

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

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

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

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

 #include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector> 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 2000000000
#define eps 1e-6 typedef long long ll;
const double pi=acos(-);
bool vis[][],visp[];
struct point{
int x,y;
point(){}
point(int x,int y):x(x),y(y){}
point operator - (point a){return point(x-a.x,y-a.y);}
point operator + (point a){return point(x+a.x,y+a.y);}
bool operator == (point a){return x==a.x&&y==a.y;}
}p[];
int tx,ty;
int dcmp(double x){
if(x>eps)return ;
if(x<-eps)return -;
return ;
}
int cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
int dot(point a,point b){
return a.x*b.x+a.y*b.y;
}
double length(point a){
return sqrt(dot(a,a));
}
bool cmp(const int& a,const int&b){
double a1=atan2(p[a].y-ty,p[a].x-tx);
double a2=atan2(p[b].y-ty,p[b].x-tx);
return a1<a2;
}
bool InPoly(vector <point> poly,point p0){
int n=poly.size();
int cn=;
for(int i=;i<n;i++){
int j=(i+)%n;
if(poly[i]==p0||poly[j]==p0)return false;
int d1=poly[i].y-p0.y,d2=poly[j].y-p0.y;
int c=cross(poly[j]-poly[i],p0-poly[i]);
if(c== && dot(poly[i]-p0,poly[j]-p0)<)return ;
else if(c==)return ;
if(c> && d1< && d2>=)cn++;
if(c< && d1>= && d2<)cn--;
}
return cn;
}
double area(vector <point> poly){
int n=poly.size();
double a=;
for(int i=;i<n;i++)a+=cross(poly[i],poly[(i+)%n]);
return a;
}
vector <int> g[];
vector <point> poly;
vector <int> tp; int main(){
//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
int t;
scanf("%d",&t);
while(t--){
int n,k,m,ans=;
memset(vis,,sizeof vis);
scanf("%d",&n);
for(int i=;i<=n;i++)g[i].clear();
for(int i=;i<=n;i++){
int u,v;
scanf("%d",&u);
scanf("%d%d%d",&p[u].x,&p[u].y,&m);
while(m--){
scanf("%d",&v);
g[u].push_back(v);
}
}
scanf("%d",&k);
for(int i=;i<=n;i++){
tx=p[i].x;ty=p[i].y;
sort(g[i].begin(),g[i].end(),cmp);
}
for(int i=;i<=n;i++)
for(int u=,j=g[i][u];u<g[i].size();u++,j=g[i][u])if(!vis[i][j]){
vis[i][j]=;
tp.clear();
tp.push_back(i);
tp.push_back(j);
bool flag=true;
memset(visp,,sizeof visp);
visp[i]=visp[j]=true;
while(flag){
flag=;
int now=tp[tp.size()-];
int sec=tp[tp.size()-];
if(g[now].size()==){flag=;break;}
int e;
for(e=;e<g[now].size();e++)if(g[now][e]==sec)break;
int x=g[now][(e+)%g[now].size()];
if(vis[now][x]){flag=false;break;}
vis[now][x]=;
tp.push_back(x);
if(visp[x])break;
visp[x]=true;
}
if(!flag)continue;
poly.clear();
int last=tp[tp.size()-];
int pos;
for(pos=tp.size()-;pos>=;pos--){
poly.push_back(p[tp[pos]]);
//printf("%d ",tp[pos]);
if(last==tp[pos])break;
}
//printf("polygon = %d\n",poly.size());
if(poly.size()==k){
flag=true;
for(int u=;u<=n;u++)if(InPoly(poly,p[u]))
{flag=false;break;}
if(flag && dcmp(area(poly))>)ans++;
}
}
printf("%d\n",ans);
}
return ;
}

 

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[],y[];
double r;
int cal_above(double k){
int i,cnt=;
for(i=;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=;
for(i=;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>){
int i,ans=;
scanf("%d",&n);
for(i=;i<n;i++)scanf("%d%d",&x[i],&y[i]);
double k;
for(i=;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=,c2=;
for(i=;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 ;
}

H - Mondriaan's Dream

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

 #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[][<<];
void dfs(int sta,int cur,int ori,int beg){
dp[cur+][sta]+=dp[cur][ori];
int bas=<<beg;
for(int i=beg;i<=w-;i++){
if((sta&bas)==)
dfs(sta|bas,cur,ori,i+);
bas<<=;
}
}
int main(){ while(scanf("%d%d",&h,&w) && w){
int i,j,FULL=(<<w)-;
memset(dp,,sizeof dp);
dp[][FULL]=;
for(i=;i<h;i++)
for(j=;j<(<<w);j++){
dfs(FULL^j,i,j,);
}
printf("%lld\n",dp[h][FULL]);
}
return ;
}

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[][][],g[][][];
int ans,n,m,k,l;
int dx[]={,-,,,,},dy[]={,,,-,,},dz[]={,,,,,-};
void bfs(int now){
int q[**],from=,to=;
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=;d<;d++){
ux=vx+dx[d];
uy=vy+dy[d];
uz=vz+dz[d];
if(ux>=&&ux<n && uy>=&&uy<m && uz>=&&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]=;
}
}
}
}
}
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,,sizeof vis);
memset(g,,sizeof g);
int pos,x,y,z;
while(l--){
scanf("%d",&pos);
x=pos%n+;
y=(pos%(m*n))/n+;
z=pos/(m*n)+;
g[x][y][z]=;
}
n+=;m+=;k+=;
ans=;
int i,j;
for(i=;i<m;i++)
for(j=;j<k;j++)if(!vis[][i][j])bfs(j*m*n+i*n+);
for(i=;i<m;i++)
for(j=;j<k;j++)if(!vis[n-][i][j])bfs(j*m*n+i*n+n-);
for(i=;i<n;i++)
for(j=;j<k;j++)if(!vis[i][][j])bfs(j*m*n+i);
for(i=;i<n;i++)
for(j=;j<k;j++)if(!vis[i][m-][j])bfs(j*m*n+(m-)*n+i);
for(i=;i<n;i++)
for(j=;j<m;j++)if(!vis[i][j][])bfs(j*n+i);
for(i=;i<n;i++)
for(j=;j<m;j++)if(!vis[i][j][k-])bfs(j*n+i+(k-)*m*n);
printf("The number of faces needing shielding is %d.\n",ans);
}
return ;
}

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[][],vis[][][],d[][][];
int n,ans;
void bfs(int px,int py,int pz){
int q[**];
int from=,to=,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]=;
if(ux==uy&&uy==uz){ans=d[ux][uy][uz];return;}
from++;
int i;
for(i=;i<=n;i++)if(g[ux][i]==g[uy][uz]&&!vis[i][uy][uz]){
d[i][uy][uz]=min(d[i][uy][uz]>=?d[i][uy][uz]:INF,+d[ux][uy][uz]);
q[to++]=i*N*N+uy*N+uz;
}
for(i=;i<=n;i++)if(g[uy][i]==g[uz][ux]&&!vis[ux][i][uz]){
d[ux][i][uz]=min(d[ux][i][uz]>=?d[ux][i][uz]:INF,+d[ux][uy][uz]);
q[to++]=ux*N*N+i*N+uz;
}
for(i=;i<=n;i++)if(g[uz][i]==g[ux][uy]&&!vis[ux][uy][i]){
d[ux][uy][i]=min(d[ux][uy][i]>=?d[ux][uy][i]:INF,+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,,sizeof vis);
memset(d,-,sizeof d);
memset(g,,sizeof g);
int i,j;
char s[];
for(i=;i<=n;i++)
for(j=;j<=n;j++){
scanf("%s",s);
g[i][j]=s[]-'a'+;
}
ans=-;
d[p1][p2][p3]=;
bfs(p1,p2,p3);
if(ans>=)printf("%d\n",ans);
else printf("impossible\n");
}
return ;
}

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 200000000 typedef long long ll;
int g[][];
char sq[][];
int main(){
//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
int m,t=;
while(scanf("%d",&m) && m){
int i,j;
memset(sq,,sizeof sq);
memset(g,,sizeof g);
for(i=;i<m;i++)
for(j=;j<m;j++)scanf("%d",&g[i][j]);
for(i=;i<m;i++)
for(j=;j<m;j++)if(!g[i][j]){
if(i && (g[i-][j]==||g[i-][j]==||g[i-][j]==))g[i][j]+=;
if(!j || (g[i][j-]==||g[i][j-]==||g[i][j-]==-))g[i][j]+=;
}
int px,py;;
for(i=;i<m;i++)
for(j=;j<m;j++){
px=i*;py=j*+;
sq[px][py]='O';
if(g[i][j]==||g[i][j]==||g[i][j]==-){sq[px-][py]='|';sq[px-][py]='H';}
if(g[i][j]==||g[i][j]==||g[i][j]==-){sq[px+][py]='|';sq[px+][py]='H';}
if(g[i][j]==||g[i][j]==||g[i][j]==){sq[px][py-]='-';sq[px][py-]='H';}
if(g[i][j]==||g[i][j]==||g[i][j]==){sq[px][py+]='-';sq[px][py+]='H';}
} if(t>)printf("\n");
printf("Case %d:\n\n",t);
for(i=;i<*m+;i++)printf("*");
printf("\n");
for(i=;i<=*m-;i++){
printf("*");
for(j=;j<=*m;j++){
if(!sq[i][j])printf(" ");
else printf("%c",sq[i][j]);
}
printf("*\n");
}
for(i=;i<*m+;i++)printf("*");
printf("\n"); t++;
}
return ;
}

D - Split Windows

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

 #include <stdio.h>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm> using namespace std;
typedef pair<int,int> pii;
struct node{
char v;
int h,w;
int left,right;
}tr[];
char buf[],map[][];
int sz;
char* build(int now,char *s){
char *p=s;
if(*p==)return p;
tr[now].v=*p;
if(*(p+)){
if(*p<='Z'&&*p>='A')return p+;
else{
tr[now].left=++sz;tr[now].right=++sz;
p=build(tr[now].left,p+);
p=build(tr[now].right,p);
return p;
}
}
}
void dfs(int now){
if(tr[now].v!='|'&&tr[now].v!='-')tr[now].w=tr[now].h=;
else{
dfs(tr[now].left);dfs(tr[now].right);
if(tr[now].v=='|'){
tr[now].w=tr[tr[now].left].w+tr[tr[now].right].w;
tr[now].h=max(tr[tr[now].left].h,tr[tr[now].right].h);
}else{
tr[now].h=tr[tr[now].left].h+tr[tr[now].right].h;
tr[now].w=max(tr[tr[now].left].w,tr[tr[now].right].w);
}
}
}
void cal(int now,int w,int h){
tr[now].w=w;tr[now].h=h;
if(tr[now].v<='Z'&&tr[now].v>='A')return; if(tr[now].v=='-'){
int down=tr[now].h*tr[tr[now].right].h/(tr[tr[now].left].h+tr[tr[now].right].h);
cal(tr[now].left,tr[now].w,tr[now].h-down);
cal(tr[now].right,tr[now].w,down);
}
else if(tr[now].v=='|'){
int down=tr[now].w*tr[tr[now].right].w/(tr[tr[now].left].w+tr[tr[now].right].w);
cal(tr[now].left,tr[now].w-down,tr[now].h);
cal(tr[now].right,down,tr[now].h);
}
}
void make_map(int now,int x,int y){
if(tr[now].v!='|'&&tr[now].v!='-'){
map[x][y]=tr[now].v;
int w=tr[now].w,h=tr[now].h;
for(int i=x+;i<x+h;i++)if(!map[i][y])map[i][y]='|';
if(!(map[x+h][y]<='Z'&&map[x+h][y]>='A'))map[x+h][y]='*';
for(int i=x+;i<x+h;i++)if(!map[i][y+w])map[i][y+w]='|';
if(!(map[x+h][y+w]<='Z'&&map[x+h][y+w]>='A'))map[x+h][y+w]='*';
if(!(map[x][y+w]<='Z'&&map[x][y+w]>='A'))map[x][y+w]='*';
for(int i=y+;i<y+w;i++)if(!map[x][i])map[x][i]='-';
for(int i=y+;i<y+w;i++)if(!map[x+h][i])map[x+h][i]='-';
}
else if(tr[now].v=='-'){
make_map(tr[now].left,x,y);
make_map(tr[now].right,x+tr[tr[now].left].h,y);
}
else{
make_map(tr[now].left,x,y);
make_map(tr[now].right,x,y+tr[tr[now].left].w);
}
}
int main(){
//freopen("r.in","r",stdin);freopen("r.out","w",stdout);
int t,cs=;
scanf("%d",&t);
while(t--){
scanf("%s",buf);
sz=;
memset(map,,sizeof map);
build(sz,buf);
dfs();
cal(,tr[].w,tr[].h);
make_map(,,);
printf("%d\n",cs++);
for(int i=;i<=tr[].h;i++){
for(int j=;j<=tr[].w;j++){
if(map[i][j])printf("%c",map[i][j]);
else printf(" ");
}
printf("\n");
}
}
return ;
}

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[],next[*],to[*],inc[],g[][];
int n,m,edge;
int q[],res;
int toposort(){
stack <int> s;
int i,du[];
for(i=;i<;i++)du[i]=inc[i];
res=;
for(i=;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!=-){
du[to[e]]--;
if(!du[to[e]])s.push(to[e]);
e=next[e];
}
}
if(res<n)return -;
for(i=;i<n-;i++)if(!g[q[i]][q[i+]])return ;
return ;
}
int main(){
//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
char str[];
while(scanf("%d%d",&n,&m) && n){
int u,v,flag=;
memset(first,-,sizeof first);
memset(next,-,sizeof next);
memset(inc,,sizeof inc);
memset(g,,sizeof g);
edge=;
for(int i=;i<=m;i++){
scanf("%s",str);
if(flag)continue;
u=str[]-'A'+;
v=str[]-'A'+;
next[edge]=first[u];
first[u]=edge;to[edge++]=v;
inc[v]++;
g[u][v]=;
res=;
flag=toposort();
if(flag==){
printf("Sorted sequence determined after %d relations: ",i);
for(int j=;j<n;j++)printf("%c",'A'+q[j]-);
printf(".\n");
}else if(flag==-){
printf("Inconsistency found after %d relations.\n",i);
}
}
if(!flag)printf("Sorted sequence cannot be determined.\n");
}
return ;
}

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=;
char *p=s+; SKIP(p);
if(*p=='/')++p,shan=;
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)>)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)>)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 ;
}
else s++;
}
return ;
}
int main(){
//freopen("a.in","r",stdin);freopen("a.out","w",stdout);
char s[];
gets(s);
int flag=;
while(strcmp(s,END)){
STACK_CLEAR;
st.clear();
gets(s);
flag=;
root=;
while(strcmp(s,START)&&strcmp(s,END)){
if(!flag||feed(s)==)flag=;
gets(s);
}
if(!flag||root!=||!ele.empty())printf("non well-formed\n");
else printf("well-formed\n");
} return ;
}

狗狗40题~(Volume A)的更多相关文章

  1. 狗狗40题~ (Volume C)

    A - Triangles 记忆化搜索呗.搜索以某三角形为顶的最大面积,注意边界情况. #include <stdio.h> #include <cstring> #inclu ...

  2. 狗狗40题~(Volume B)

    H - Sorting Slides 应该是个二分匹配的模板题的,但我还不会写 = = 其实数据规模很小,就用贪心的方法就水过了(没加vis判冲突wa了几发,从此开始艰难的没有1A 的生活) #inc ...

  3. JAVA经典算法40题及解答

    JAVA经典算法40题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...

  4. JAVA经典算法40题

    1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...

  5. JAVA经典算法40题(原题+分析)之分析

    JAVA经典算法40题(下) [程序1]   有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1.程序分析:  ...

  6. JAVA经典算法40题(原题+分析)之原题

    JAVA经典算法40题(上) [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [程 ...

  7. JAVA经典算法40题面向过程

    JAVA经典算法40题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...

  8. 剑指offer 面试40题

    面试40题: 题目:最小的k个数 题:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题代码一: # -*- coding ...

  9. java经典算法40题-附带解决代码

    前一段时间工作比较闲,每天没有代码敲的日子有点无聊,于是为了保证自己的编程逻辑力的日常清醒,故百度了一些经典的java算法,然后自己思考编程解决问题,虽然那些东西比较基础了,但是有些题目小编看到了也是 ...

随机推荐

  1. ExtJs MVC应用架构示例

    项目目录结构 (源码)2. app.js Ext.Loader.setConfig({ enabled : true, paths : { 'Ext' : 'extjs', 'App' : 'app' ...

  2. 用c语言程序对显存进行操作

    一.基础研究 我们之前研究过变量.数组.函数和指针,他们都可以看作是内存中存储的一段数据,当程序需要用到它们时,会通过它们的地址找到它们并进行调用,只是调用的用途不同而已:变量和数组元素是作为常量来处 ...

  3. library cache lock

    SESSION 34 执行存储过程: SESSION 43 编译存储过程: SESSION 25 删除存储过程: 1.查询查看library cache lock等待事件的相关会话 SQL> s ...

  4. delphi 句柄

    句柄Handle顾名思义就是把柄,把手的意思 ,得到了某对象的句柄可以任意控制此对象 .句柄是一种指向指针的指针.不是每个组件都有句柄,只有窗口控件等(*.模块(module)*.任务(task)*. ...

  5. visual studio 调试grunt

    原文地址: https://yoavniran.wordpress.com/2015/06/25/debug-grunt-tasks-in-visual-studio-2015/

  6. P - 奔小康赚大钱 - hdu 2255(带权值的匹配)

    分析:这是一个KM的模板题,也就不多说了,KM最复杂的情况都能过,下面是没有优化过的代码: ****************************************************** ...

  7. kindle paperwhite 使用说明

    calibre,eink必备转换软件. easypub,lucida制作的软件,支持txt to epub:txt to mobi,可以实现目录. 售后电话:400 817 0100 正常的设计格式转 ...

  8. bt5全称是Back Track five,是继BT3,BT4之后的最新版,这是一个linux环境的便携系统,可以放到U盘或者硬盘中启动,对本身硬盘没有影响,无需在本地安装。

    是圈内非常著名的黑客攻击平台,是一个封装好的Linux操作系统,内置大量的网络安全检测工具以及黑客破解软件等. Back Track因可以方便的破解无线网络而出名,其中内置的spoonwep2是一个非 ...

  9. QT5: QApplication, no such file or directory

    In QT5, when I use this: #include<QApplication>, QT tells :no such file or directory, even tho ...

  10. [Angular 2] Passing Template Input Values to Reducers

    Angular 2 allows you to pass values from inputs simply by referencing them in the template and passi ...