今年北邮机试不让带资料了,预计今后都不会再让带资料,影响还是蛮大的。
Problem A 二进制
题目
32位二进制数X,输出X+1和X+3之后的32位二进制数
输入
第一行输入一个整数T,代表测试数据组数。
接下来的T行,每行输入一个32位二进制数
输出
对每组测试数据,输出两行,第一行为X+1,第二行为X+3
测试用例
输入
2
00000000000000000000000000000000
00000000000000000000000000000001
输出
00000000000000000000000000000001
00000000000000000000000000000011
00000000000000000000000000000010
00000000000000000000000000000100
思路
笨比做法,把32位二进制数转化为十进制数再转化为二进制数,注意转化成的十进制数要用long long
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
char str[33];
scanf("%s",str);
long long num=0;
int l=1;
for(int i=31;i>=0;i--)
{
num+=(l*(str[i]-'0'));
l*=2;
}
long long num1=num+1;
int ans1[32];
int size1=0;
while(num1>0)
{
ans1[size1++]=num1%2;
num1/=2;
}
for(int i=31;i>=size1;i--)
printf("0");
for(int i=size1-1;i>=0;i--)
printf("%d",ans1[i]);
printf("\n");
long long num2=num+3;
int ans2[32];
int size2=0;
while(num2>0)
{
ans2[size2++]=num2%2;
num2/=2;
}
for(int i=31;i>=size2;i--)
printf("0");
for(int i=size2-1;i>=0;i--)
printf("%d",ans2[i]);
printf("\n");
}
return 0;
}
Problem B 二叉树
题目
计算二叉树两个结点的最短距离。
输入
第一行输入测试数据组数T
第二行输入n,m 。n代表结点的个数,m代表要查询的数据组数
接下来n行,每行输入两个数,代表1~n结点的孩子结点,如果没有孩子结点则输入-1.根节点为1.
接下来m行,每行输入两个数,代表要查询的两个结点
输出
每组测试数据输出m行,每行是两个结点之间的最短距离
测试用例
输入
1
8 4
2 3
4 5
6 -1
-1 -1
-1 7
-1 -1
8 -1
-1 -1
1 6
4 6
4 5
8 1
输出
2
4
2
4
思路
其实这道题应该找二叉树的公共祖先。但是机试的时候,一方面是我之前没有写过二叉树公共祖先,一方面是懒,直接把二叉树转化成了父节点和子节点距离为1的图,然后dijkstra算了一下最短路径
代码
#include<bits/stdc++.h>
using namespace std;
const int N=100;
const int inf=1e10+10;
vector<int>edge[N],cost[N];
struct Node
{
int v,w;
Node(){}
Node(int v,int w):v(v),w(w){}
bool operator <(const Node &A)const
{
return w>A.w;
}
};
int dist[N];
bool vis[N];
void dijkstra(int start)
{
for(int i=1;i<=N;i++) dist[i]=inf,vis[i]=0;
dist[start]=0;
priority_queue <Node> Q;
Q.push(Node(start,0));
while(!Q.empty())
{
Node tmp=Q.top();Q.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=1;
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i],w=cost[u][i];
if(dist[v]>dist[u]+w)
{
dist[v]=dist[u]+w;
Q.push(Node(v,dist[v]));
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++) edge[i].clear(),cost[i].clear();
for(int i=1;i<=n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(u!=-1)
{
edge[i].push_back(u);
cost[i].push_back(1);
edge[u].push_back(i);
cost[u].push_back(1);
}
if(v!=-1)
{
edge[i].push_back(v);
cost[i].push_back(1);
edge[v].push_back(i);
cost[v].push_back(1);
}
}
for(int i=1;i<=m;i++)
{
int str,end;
scanf("%d%d",&str,&end);
dijkstra(str);
printf("%d\n",dist[end]);
}
}
}
return 0;
}
Problem C 最短路径
题目
计算从城市1到城市n的最短路径长度。分为白天和黑夜,黑夜会关掉若干条线路,分别计算城市1到城市n的在白天和黑夜的最短路径长度。保证每个城市与其他城市必有连接。两个城市之间可能有多重边
输入
第一行输入T,测试用例组数
第二行输入n,m,k. n是城市数,m是边数,k是黑夜关闭的边数(n<=50)
接下来m行,每行输入三个数x,y,z,代表城市x和城市y之间的距离
最后一行k个数,代表晚上关闭的线路序号
输出
每组数据输出两行,分别代表白天和黑夜,城市1到n的最短路径长度
测试用例
输入
1
4 4 1
1 2 1
2 3 1
3 4 1
1 4 1
4
输出
1
3
思路
上来一读题,读到节点数小于等于50,马上写了个Floyd,用例跑过之后,提交,结果发现oj多了提醒:可能会有重边。遂改成dijkstra,用vector建图,本来想的是建好了图之后,把黑夜中要关闭的边从vector中erase掉就ok,奈何基础还是比较差,erase之前也用的比较少,本地error都解决不了。改了思路,把输入的边存一下,在计算黑夜的最短路径的时候重新建图,不把黑夜中要关闭的边加进去。幸好这题测试数据规模小,笨比做法也能搞定。119分钟提交的第3题,最后一分钟过了,心情着实经历了一番大起大落。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=100;
const int inf=1e10+10;
vector<int>edge[N],cost[N];
struct Node
{
int v,w;
Node(){}
Node(int v,int w):v(v),w(w){}
bool operator <(const Node &A)const
{
return w>A.w;
}
};
struct road
{
int u,v,w;
};
int dist[N];
bool vis[N];
void dijkstra(int start)
{
for(int i=1;i<=N;i++) dist[i]=inf,vis[i]=0;
dist[start]=0;
priority_queue <Node> Q;
Q.push(Node(start,0));
while(!Q.empty())
{
Node tmp=Q.top();Q.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=1;
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i],w=cost[u][i];
if(dist[v]>dist[u]+w)
{
dist[v]=dist[u]+w;
Q.push(Node(v,dist[v]));
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) edge[i].clear(),cost[i].clear();
road tmp[101];
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
tmp[i].u=u;tmp[i].v=v;tmp[i].w=w;
edge[u].push_back(v);
cost[u].push_back(w);
edge[v].push_back(u);
cost[v].push_back(w);
}
dijkstra(1);
printf("%d\n",dist[n]);
for(int i=1;i<=n;i++) edge[i].clear(),cost[i].clear();
int clo[101];
for(int i=1;i<=k;i++)
scanf("%d",&clo[i]);
for(int i=1;i<=m;i++)
{
bool flag=false;
for(int j=1;j<=k;j++)
{
if(i==clo[j])
{
flag=true;
break;
}
}
if(flag==false)
{
int u,v,w;
u=tmp[i].u;v=tmp[i].v;w=tmp[i].w;
edge[u].push_back(v);
cost[u].push_back(w);
edge[v].push_back(u);
cost[v].push_back(w);
}
}
dijkstra(1);
printf("%d\n",dist[n]);
}
return 0;
}