# 数据结构与算法部分习题题解

### Poj 1686 Lazy Math Instructor

Code:

#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
typedef unsigned long long ull;
stack<ull> num;
stack<int> opt;
inline int getopt(char s) {
switch(s) {
case '+':
return 1;
case '-':
return 2;
case '*':
return 3;
}
return 0;
}
ull a[60];
inline ull getnum(char s) {
if ('0'<=s&&s<='9') return s-'0';
if ('a'<=s&&s<='z') return a[s-'a'];
if ('A'<=s&&s<='Z') return a[s-'A'+26];
return 0;
}
inline ull _text(string s) {
int l=s.size();
while (!num.empty()) num.pop();
while (!opt.empty()) opt.pop();
num.push(0);opt.push(1);
for (int i=0;i<l;i++) {
if (s[i]==' '||s[i]=='\t') continue;
if (s[i]=='+'||s[i]=='-'||s[i]=='*') {
int t=getopt(s[i]);
opt.push(t);
continue;
}
if (s[i]=='(') {
num.push(0);opt.push(1);
continue;
}
ull t;
if (s[i]==')') {t=num.top();num.pop();}
else t=getnum(s[i]);
ull u=num.top();
int v=opt.top();
num.pop();opt.pop();
switch (v) {
case 1:
u+=t;
break;
case 2:
u-=t;
break;
case 3:
u*=t;
break;
}
num.push(u);
}
return num.top();
}
string s,t;
int main(){
int __;
cin>>__;
getline(cin,s);
while (__--) {
bool flag=0;
getline(cin,s);
getline(cin,t);
for (int _=1;_<=20;_++) {
for (int i=0;i<26*2;i++) a[i]=rand();
if (_text(s)!=_text(t)) {
printf("NO\n");
flag=1;
break;
}
}
if (!flag) printf("YES\n");
}
return 0;
}

### poj 1961:Period

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
#define maxn 1001000
char s[maxn];
int f[maxn],b[maxn];
int main(){
int cnt=1;
scanf("%d",&n);
while (n!=0) {
printf("Test case #%d\n",cnt++);
scanf("%s",s);
f[0]=-1,f[1]=0;
for (int i=2;i<=n;i++) {
int k=f[i-1];
while (k>=0&&s[k]!=s[i-1]) k=f[k];
f[i]=k+1;
}
for (int i=2;i<=n;i++) {
b[i]=0;
if (i%2==0&&f[i]==i/2) b[i]=2;
if (b[f[i]]&&i%(b[f[i]]+1)==0&&f[i]/b[f[i]]==i/(b[f[i]]+1))
b[i]=b[f[i]]+1;
if (b[i]) printf("%d %d\n",i,b[i]);
}
printf("\n");
scanf("%d",&n);
}
return 0;
}

### 表达式•表达式树•表达式求值

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
struct node{
char inf;
int pos,dep;
node* ch[2];
node(){
ch[0]=ch[1]=NULL;
}
};
char s[500];
inline int findopt(int l,int r) {
int cnt=0,tmp1=0,tmp2=0;
for (int i=r;i>=l;i--) {
if (s[i]=='(') cnt++;
if (s[i]==')') cnt--;
if (cnt!=0) continue;
if ((!tmp1)&&(s[i]=='+'||s[i]=='-')) tmp1=i;
if ((!tmp2)&&(s[i]=='*'||s[i]=='/')) tmp2=i;
}
if (tmp1) return tmp1;
return tmp2;
}
node* build(int l,int r) {
if (l==r) {
node* t=new node;
t->inf=s[l];
return t;
}
node *pre=new node;
int t=findopt(l,r);
if (t==0) return build(l+1,r-1);
pre->inf=s[t];
pre->ch[0]=build(l,t-1);
pre->ch[1]=build(t+1,r);
return pre;
}
int mxdep;
inline void dfs(node *u){
if (u==NULL) return ;
if (u->ch[0]) {
u->ch[0]->pos=(u->pos<<1)-1;
u->ch[0]->dep=u->dep+1;
}
if (u->ch[1]) {
u->ch[1]->pos=(u->pos<<1);
u->ch[1]->dep=u->dep+1;
}
mxdep=max(mxdep,u->dep);
dfs(u->ch[0]);dfs(u->ch[1]);
printf("%c",u->inf);
}
char st[100][480010];
inline void print(node *u){
if (u==NULL) return ;
int dep=mxdep-u->dep+1,pos=(1<<(dep-1))+(1<<dep)*(u->pos-1);
st[u->dep*2][pos]=u->inf;
if (u->ch[0]) st[u->dep*2+1][pos-1]='/';
if (u->ch[1]) st[u->dep*2+1][pos+1]='\\';
print(u->ch[0]);print(u->ch[1]);
return ;
}
map<char,int> Map;
inline int clac(node *u) {
if (Map.find(u->inf)!=Map.end()) return Map[u->inf];
int x=clac(u->ch[0]),y=clac(u->ch[1]);
if (u->inf=='-') return x-y;
if (u->inf=='+') return x+y;
if (u->inf=='*') return x*y;
if (u->inf=='/') return x/y;
return 0;
}
int main(){
scanf("%s",s+1);
int len = strlen(s+1);
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++) {
char tmp[2];int t;
scanf("%s%d",tmp,&t);
Map[tmp[0]]=t;
}
node *root=build(1,len);
root->pos=1;
dfs(root);
printf("\n");
print(root);
int mxlen=0;
for (int i=0;i<=mxdep*2;i++) {
for (int j=1;j<480000;j++)
if (!st[i][j]) st[i][j]=' ';
for (int j=479999;st[i][j]==' ';j--) st[i][j]=0;
printf("%s\n",st[i]+1);
mxlen=max(mxlen,int(strlen(st[i]+1)));
}
printf("%d\n",clac(root));
return 0;
}

### poj 2049 Finding Nemo

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define maxn 41000
#define maxm 180000
#define inf 0x7fffffff
struct edges{
int to,next,dis;
}edge[maxm];
int n,m,id[230][230],Map[maxn][4];
int nxt[maxn],cnt,l;
inline void addedge(int x,int y,int z){
edge[++l]=(edges){y,nxt[x],z};nxt[x]=l;
}
queue<int> q;
bool b[maxn];int dis[maxn];
inline void spfa(int u){
for (int i=1;i<=cnt;i++) dis[i]=inf;
dis[u]=0;
q.push(u);
while (!q.empty()) {
int u=q.front();q.pop();
b[u]=0;
for (int i=nxt[u];i;i=edge[i].next) {
if (dis[edge[i].to]<=dis[u]+edge[i].dis) continue;
dis[edge[i].to]=dis[u]+edge[i].dis;
if (!b[edge[i].to]) {
b[edge[i].to]=1;
q.push(edge[i].to);
}
}
}
}
int w[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int main(){
for (int i=0;i<=200;i++)
for (int j=0;j<=200;j++) id[i][j]=++cnt;
while (scanf("%d%d",&m,&n)!=EOF) {
if (n==-1||m==-1) break;
memset(nxt,0,sizeof(nxt));
l=0;
memset(Map,0,sizeof(Map));
for (int i=1;i<=m;i++) {
int x,y,d,t;
scanf("%d%d%d%d",&x,&y,&d,&t);
for (int j=0;j<t;j++) {
int u=id[x+j*(d^1)][y+j*d],v=id[x+j*(d^1)-d][y+j*d-(d^1)];
Map[u][d*2+1]=Map[v][d*2]=1;
}
}
for (int i=1;i<=n;i++) {
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
int u=id[x][y],v=id[x-d][y-(d^1)];
Map[u][d*2+1]=Map[v][d*2]=-1;
}
for (int i=0;i<=200;i++)
for (int j=0;j<=200;j++)
for (int k=0;k<4;k++) {
int u=i+w[k][0],v=j+w[k][1];
if (u<0||u>200||v<0||v>200) continue;
}
spfa(id[0][0]);
double v,u;
scanf("%lf%lf",&u,&v);
u=min(u,200.0),v=min(v,200.0);
printf("%d\n",dis[id[int(u)][int(v)]]==inf?-1:dis[id[int(u)][int(v)]]);
}
return 0;
}

### POJ 2049 The Peanuts

Code：

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int> ii;
#define maxn 55
#define fi first
#define se second
int a[maxn][maxn];
ii id[maxn*maxn];
bool cmp(ii x, ii y) {
return a[x.fi][x.se]>a[y.fi][y.se];
}
int main(){
int _;
scanf("%d",&_);
while (_--) {
int n,m,k,l=0;
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) {
scanf("%d",&a[i][j]);
id[++l]=ii(i,j);
}
sort(id+1,id+l+1,cmp);
if (id[1].fi+id[1].fi+1>k) {
printf("%d\n",0);
continue;
}
int t=id[1].fi+1,ans=a[id[1].fi][id[1].se];
for (int i=2;i<=l;i++) {
int dis=abs(id[i].fi-id[i-1].fi)+abs(id[i].se-id[i-1].se)+1;
if (t+dis+id[i].fi>k) break;
t+=dis;
ans+=a[id[i].fi][id[i].se];
}
printf("%d\n",ans);
}
return 0;
}

### 发现它，抓住它

Code：

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 101000
int fa[maxn],rela[maxn];
int findfa(int x) {
if (fa[x]==x) return x;
findfa(fa[x]);
rela[x]^=rela[fa[x]];
fa[x]=fa[fa[x]];
return fa[x];
}
int main(){
int _;
scanf("%d",&_);
while (_--) {
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) fa[i]=i,rela[i]=0;
for (int i=1;i<=m;i++) {
int x,y,u,v;
char opt[3];
scanf("%s%d%d",opt,&x,&y);
switch(opt[0]) {
case 'A' :
if (findfa(x)==findfa(y)) {
if (rela[x]==rela[y])
printf("In the same gang.\n");
else printf("In different gangs.\n");
}else printf("Not sure yet.\n");
break;
case 'D':
u=findfa(x),v=findfa(y);
if (u==v) continue;
fa[u]=v;
rela[u]=rela[x]^rela[y]^1;
break;
}
}
}
}

### Poj 1830 开关问题

Code：

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 32
int b[maxn][maxn];
int main(){
int _;
scanf("%d",&_);
while (_--) {
int n,cnt=0;
scanf("%d",&n);
memset(b,0,sizeof(b));
for (int i=1;i<=n;i++) scanf("%d",&b[i][n+1]);
for (int i=1;i<=n;i++) {
int x;
scanf("%d",&x);
b[i][n+1]^=x;
}
for (;;) {
int x,y;
scanf("%d%d",&x,&y);
if (x==0&&y==0) break;
b[y][x]=1;
}
for (int i=1;i<=n;i++) b[i][i]=1;
int l=1;
for (int i=1;i<=n+1;i++) {
for (int j=l;j<=n;j++)
if (b[j][i]) {
swap(b[l],b[j]);
break;
}
if (!b[l][i]) {cnt++;continue;}
for (int j=l+1;j<=n;j++) {
if (!b[j][i]) continue;
for (int k=i;k<=n+1;k++) b[j][k]^=b[l][k];
}
l++;
}
int flag=0;
for (int i=1;i<=n;i++) {
if (!b[l-1][i]) continue;
flag=1;
}
if (!flag) printf("Oh,it's impossible~!!\n");
else printf("%d\n",1<<(cnt-1));
}
return 0;
}

### Poj 1785 Binary Search Heap Construction

Code：

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
#include<cstdlib>
using namespace std;
typedef pair<int,int> ii;
#define maxn 51000
priority_queue<ii> q;
string label[maxn];
ii f[maxn][30];
int findmx(int l,int r) {
int ans=0;
for (int i=23;i>=0;i--)
if (l+(1<<i)-1<=r) {
l+=(1<<i);
}
return ans;
}
void dfs(int u,int l,int r) {
putchar('(');
if (l<u) dfs(findmx(l,u-1),l,u-1);
if (u<r) dfs(findmx(u+1,r),u+1,r);
putchar(')');
}
string st[maxn];
int main(){
for (;;){
int n;
scanf("%d",&n);
if (!n) break;
for (int i=1;i<=n;i++) cin>>st[i];
sort(st+1,st+1+n);
for (int i=1;i<=n;i++) {
string s=st[i];
int pos=s.find('/');
label[i]=s.substr(0,pos);
}
for (int i=1;(1<<i)<=n;i++)
for (int j=1;j+(1<<i)-1<=n;j++)
f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);
dfs(findmx(1,n),1,n);
puts("");
}
return 0;
}

### Poj 3735 Training little cats

Code：

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 11000
typedef long long ll;
int r[maxn],set[maxn],tset[maxn],tr[maxn];
int ansr[maxn],tansr[maxn];
int n,m,k;
int main(){
while (scanf("%d%d%d",&n,&m,&k)!=EOF) {
if (n==0&&m==0&&k==0) break;
for (int i=1;i<=k;i++) {
char opt;
scanf("%s",&opt);
if (opt=='g') {
int x;
scanf("%d",&x);
}
if (opt=='e') {
int x;
scanf("%d",&x);
}
if (opt=='s') {
int x,y;
scanf("%d%d",&x,&y);
swap(r[x],r[y]);
}
}
for (;m;m>>=1) {
if (m&1) {
for (int i=1;i<=n;i++) {
tansr[i]=ansr[r[i]];
}
for (int i=1;i<=n;i++) {
ansr[i]=tansr[i];
}
}
for (int i=1;i<=n;i++) {
tr[i]=r[r[i]];
}