岗位实践小结

本来没准备写这个的,搞完之后,发现附加题还是蛮好玩的。

而且,第二天的岗位又出现了类似的题,有玩头。


主题是:dfs建树?stack建树?

题目请看SzuOj:K51

题意:给一个孩子兄弟二叉树的先序遍历,找到原来树的句柄。

如:AB0C000 得到A->BC


一个想法是栈建树,然后算高度root=left?left+1:1,

第二个想法是直接dfs,直到找到第一个变黑的点。


然后第二天的岗位K62

题意:给两幅黑白图的先序遍历,然后问合并后的黑点个数

直接dfs就好,代码700b


代码如下:

1.1

#include <cstdio>
#include <cstring>
#include <stack>
#include <iostream>
 
using namespace std;
 
#define N 1500
 
char s[N];
int l[N], r[N], h[N], ans;
 
void dfs(int g){
	if(l[g]+r[g]==0) {
		h[g]=1; return;
	}
	if(l[g]) dfs(l[g]);
	if(r[g]) dfs(r[g]);
	if(l[g]) h[g]=h[l[g]]+1;
	else h[g]=1;
	if(h[g]==2){
		if(ans==-1)	ans=g;
	}
}
 
void build(){
	int i, in;
	stack<int> sa;
 
	memset(l, 0, sizeof(l));
	memset(r, 0, sizeof(r));
 
	sa.push(0);
	for(i=1; s[i]; ++i){
		in=sa.top();
		if(l[in]) r[in]=i;
		else l[in]=i;
		if(l[in] && r[in]) sa.pop();
		if(s[i]!='0') sa.push(i);
	}
 
	for(i=0; s[i]; ++i){
		if(l[i] && s[l[i]]=='0') l[i]=0;
		if(r[i] && s[r[i]]=='0') r[i]=0;
	}
}
 
 
int main()
{
	int t, x, y;
 
	scanf("%d", &t);
	while(t--){
		scanf("%s", s);
		build();
 
		ans=-1;
		dfs(0);
 
		y=ans;
		x=l[y];
		printf("%c->%c", s[y], s[x]);
		while(r[x]){
			printf("%c", s[r[x]]);
			x=r[x];
		}puts("");
	}
	return 0;
}


1,2

#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
 
using namespace std;
 
string str;
char s[100];
int x;
 
int dfs(int x, int g)
{
	if(s[x]=='0')	return 0;
 
	int l, r, ret=1;
 
	++x; l=dfs(x, x);
	++x; r=dfs(x, x);
 
	if(l) ret=l+1;
	else if(r) ret=r;
 
	if(ret==1)	str+=s[g];
	if(ret==2){
		reverse(str.begin(), str.end());
		printf("%c->%s\n", s[g], str.c_str());
		ret=3;
	}
 
	return ret;	
}
 
int main()
{
	int t;
 
	scanf("%d", &t);
	while(t--){
		scanf("%s", s);
		x=0; str=""; dfs(x, x);
	}
 
	return 0;
}


2.1

include <stdio.h>
#include <string.h>
 
#define N 40
 
char s[100], mat[N][N]={0};
int r;
 
void dfs(int x, int y, int l){
	if(s[r]=='f'){
		int i, j, X, Y;
 
		X=x+l; Y=y+l;
		for(i=x; i<X; ++i){
			for(j=y; j<Y; ++j)
				mat[i][j]=1;
		} return;
	}
	else if(s[r]=='e') return;
	else {
		l=l>>1;
		r++; dfs(x, y+l, l);		
		r++; dfs(x, y, l);
		r++; dfs(x+l, y, l);		
		r++; dfs(x+l, y+l, l);
	}
}
 
 
int main()
{
	scanf("%s", s);
	r=0;
	dfs(0, 0, 32);
 
	scanf("%s", s);
	r=0;
	dfs(0, 0, 32);
 
	int i, j, ans=0;
	for(i=0; i<32; ++i){
		for(j=0; j<32; ++j)
			if(mat[i][j]) ans++;
	}printf("%d\n", ans);
 
 
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值