来自zyyyyy的留言:久远的浙大机试题...
A - 找出直系亲属
如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。
当n和m为0时结束输入。
具体含义和输出格式参见样例.
3 2 ABC CDE EFG FA BE 0 0
great-grandparent -
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+10;
struct unit{
int ch;
unit *father;
unit *mother;
unit *son;
unit(): father(NULL),mother(NULL),son(NULL){};
}*save[maxn];
unit *newUnit(){
return new unit();
}
char in[10];
bool vis[maxn];
int res;
void findRelation(int x,int target,int sum){
if(vis[x]||vis[target]){
return;
}
if(x==target){
res = sum;
return;
}
if(sum>=0&&(save[x]->mother!=NULL||save[x]->father!=NULL)){
if(save[x]->mother!=NULL){
findRelation(save[x]->mother->ch, target, sum+1);
}
if(save[x]->father!=NULL){
findRelation(save[x]->father->ch, target, sum+1);
}
}
if(sum<=0&&save[x]->son!=NULL){
findRelation(save[x]->son->ch, target, sum-1);
}
}
int main(){
int n,m,i,j;
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0){
return 0;
}
getchar();
memset(vis, true, sizeof(vis));
for(i=1;i<=n;i++){
scanf("%s",in);
getchar();
for(j=0;j<3;j++){
if(in[j]!='-'){
if(vis[in[j]]){save[in[j]] = newUnit();vis[in[j]]=false;}
save[in[j]]->ch = in[j];
}
}
if(in[0]!='-'&&in[1]!='-'){
save[in[0]]->father = save[in[1]];
save[in[1]]->son = save[in[0]];
}
if(in[0]!='-'&&in[2]!='-'){
save[in[0]]->mother = save[in[2]];
save[in[2]]->son = save[in[0]];
}
}
for(i=1;i<=m;i++){
scanf("%s",in);
getchar();
res = inf;
findRelation(in[0], in[1],0);
if(res==inf){
printf("-\n");
continue;
}else if(abs(res)>=2){
for(j=abs(res)-2;j>0;j--){
printf("great-");
}
printf("grand");
}
if(res>0){
printf("child\n");
}else{
printf("parent\n");
}
}
}
return 0;
}
B - 最短路径问题
(1<n<=1000, 0<m<100000, s != t)
3 2 1 2 5 6 2 3 4 5 1 3 0 0
9 11
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define INF 0x3f3f3f
const int maxn = 1010;
struct unit{
int to;
int dis;
int cost;
unit(int a,int b,int c): to(a),dis(b),cost(c){}
};
vector<unit> E[maxn];
int n,m,s,e;
pair<int,int> d[maxn];
void init(){
int i;
for(i=1;i<=n;i++){
E[i].clear();
}
for(i=1;i<=n;i++){
d[i].first = INF;
d[i].second = INF;
}
}
bool spfa(){
priority_queue<pair<int, int> > que;
d[s].first = 0;
d[s].second = 0;
que.push(make_pair(-d[s].first, s));
while(!que.empty()){
int q = que.top().second;
if(q==e){
break;
}
que.pop();
for(int i=0;i<E[q].size();i++){
int v = E[q][i].to;
if(d[v].first>=d[q].first+E[q][i].dis){
if(d[v].first>d[q].first+E[q][i].dis){
d[v].first = d[q].first+E[q][i].dis;
d[v].second = d[q].second + E[q][i].cost;
que.push(make_pair(-d[v].first, v));
}else{
if(d[v].second>d[q].second+E[q][i].cost){
d[v].first = d[q].first+E[q][i].dis;
d[v].second = d[q].second + E[q][i].cost;
que.push(make_pair(-d[v].first, v));
}
}
}
}
}
if(d[e].first==INF){
return false;
}else{
return true;
}
}
int main(){
int i;
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0){
return 0;
}
int a,b,D,p;
init();
for(i=0;i<m;i++){
scanf("%d%d%d%d",&a,&b,&D,&p);
E[a].push_back(unit(b,D,p));
E[b].push_back(unit(a,D,p));
}
scanf("%d%d",&s,&e);
if(spfa()){
printf("%d %d\n",d[e].first,d[e].second);
}else{
printf("-1\n");
}
}
return 0;
}
C - 二叉搜索树
判断两序列是否为同一二叉搜索树序列
接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字,根据这个序列可以构造出一颗二叉搜索树。
接下去的n行有n个序列,每个序列格式跟第一个序列一样,请判断这两个序列是否能组成同一颗二叉搜索树。
2 567432 543267 576342 0
YES NO
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
int sample[2500];
bool vis1[2500];
int another[2500];
bool vis2[2500];
char in[1000];
bool judge(){
int i;
for(i=1;i<2400;i++){
if(another[i]!=sample[i]){
return false;
}
}
return true;
}
int main(){
int n,i,j;
while(~scanf("%d",&n)&&n){
getchar();
scanf("%s",in);
getchar();
int len = strlen(in);
memset(sample,0,sizeof(sample));
memset(vis1, true, sizeof(vis1));
int index;
for(i=0;i<len;i++){
index = 1;
while(!vis1[index]){
if(in[i]-'0'<=sample[index]){
index *= 2;
}else{
index = index*2+1;
}
}
sample[index] = in[i]-'0';
vis1[index] = false;
}
for(int j=1;j<=n;j++){
memset(vis2, true, sizeof(vis2));
memset(another, 0, sizeof(another));
scanf("%s",in);
getchar();
len = strlen(in);
for(i=0;i<len;i++){
index = 1;
while(!vis2[index]){
if(in[i]-'0'<=another[index]){
index *= 2;
}else{
index = index*2+1;
}
}
another[index] = in[i]-'0';
vis2[index] = false;
}
if(judge()){
printf("YES\n");
}else{
printf("NO\n");
}
}
}
return 0;
}
D - 开门人和关门人
每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签
到、签离记录,请根据记录找出当天开门和关门的人。
到、签离记录,请根据记录找出当天开门和关门的人。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为
证件号码 签到时间 签离时间
其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。
3 1 ME3021112225321 00:00:00 23:59:59 2 EE301218 08:05:35 20:56:35 MA301134 12:35:45 21:40:42 3 CS301111 15:30:28 17:00:10 SC3021234 08:00:00 11:25:25 CS301133 21:45:00 21:58:40
ME3021112225321 ME3021112225321 EE301218 MA301134 SC3021234 CS301133
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 100;
char name[maxn],in[maxn],out[maxn];
char firstIn[maxn],lastOut[maxn];
int compare(int x1,int y1,int z1,int x2,int y2,int z2){
if(x1==x2){
if(y1==y2){
if(z1==z2){
return 0;
}else if(z1>z2){
return 1;
}else{
return -1;
}
}else{
if(y1>y2){
return 1;
}else{
return -1;
}
}
}else{
if(x1>x2){
return 1;
}else{
return -1;
}
}
}
int main(){
int t,n,i,j,a,b,c;
scanf("%d",&t);
getchar();
while(t--){
scanf("%d",&n);
scanf("%s %s %s",name,in,out);
getchar();
strcpy(firstIn, name);
strcpy(lastOut, name);
int xi,yi,zi,xo,yo,zo;
sscanf(in, "%d:%d:%d", &xi,&yi,&zi);
sscanf(out, "%d:%d:%d", &xo,&yo,&zo);
for(i=2;i<=n;i++){
scanf("%s %s %s",name,in,out);
sscanf(in, "%d:%d:%d", &a,&b,&c);
if(compare(xi, yi, zi, a, b, c)>0){
xi = a, yi = b, zi = c;
strcpy(firstIn, name);
}
sscanf(out, "%d:%d:%d", &a,&b,&c);
if(compare(xo, yo, zo, a, b, c)<0){
xo = a, yo = b, zo = c;
strcpy(lastOut, name);
}
}
printf("%s %s\n",firstIn,lastOut);
}
return 0;
}
E - ZOJ问题
对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC。
是否AC的规则如下:
1. zoj能AC;
2. 若字符串形式为xzojx,则也能AC,其中x可以是N个'o' 或者为空;
3. 若azbjc 能AC,则azbojac也能AC,其中a,b,c为N个'o'或者为空;
是否AC的规则如下:
1. zoj能AC;
2. 若字符串形式为xzojx,则也能AC,其中x可以是N个'o' 或者为空;
3. 若azbjc 能AC,则azbojac也能AC,其中a,b,c为N个'o'或者为空;
zoj ozojo ozoojoo oozoojoooo zooj ozojo oooozojo zojoooo
Accepted Accepted Accepted Accepted Accepted Accepted Wrong Answer Wrong Answer
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1010;
char in[maxn];
bool killme(int p,char x){
if(in[p]!=x){
printf("Wrong Answer\n");
return true;
}
return false;
}
int main(){
while(~scanf("%s",in)){
getchar();
if(!strcmp(in, "zj")){
printf("Wrong Answer\n");
continue;
}
int a = 0,b = 0, c = 0;
int n = 0, p = 0,len = strlen(in);
while(in[p]!='z'&&p<len&&in[p]=='o'){
a++;
p++;
}
if(killme(p,'z')) continue;
p++;
while(in[p]!='j'&&p<len&&in[p]=='o'){
p++;
b++;
}
if(killme(p,'j')) continue;
p++;
while(p<len&&in[p]=='o'){
p++;
c++;
}
if(p<len&&killme(p,'o')) continue;
if(a*b==c){
printf("Accepted\n");
}else{
printf("Wrong Answer\n");
}
}
return 0;
}
F - A+B
给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。
现在请计算A+B的结果,并以正常形式输出。
现在请计算A+B的结果,并以正常形式输出。
-234,567,890 123,456,789 1,234 2,345,678
-111111101 2346912
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 15;
void change(char *s,int len,long long &a){
int p = 0;
for(int i=len-1;i>=0;i--){
if(s[i]==','){
continue;
}
if(i==0&&s[i]=='-'){
a = -a;
break;
}
a += (s[i]-'0')*pow(10, p++);
}
}
int main(){
char s1[maxn],s2[maxn];
int i,j;
while(~scanf("%s %s",s1,s2)){
getchar();
long long a = 0, b = 0;
int lena = strlen(s1), lenb = strlen(s2);
change(s1,lena,a);
change(s2,lenb,b);
printf("%lld\n",a+b);
}
return 0;
}