今日OJ
第一题为北邮机试OJ第一题
题目描述
32位二进制数X,对其进行X+1,X+3 操作,并输出。注意不能忽略前导0
输入
第一行,一个整数T,代表测试数据组数。
接着T行,输入32为二进制数
输出
对每组测试数据,输出两行,第一行为X+1,第二行为X+3.
测试样例
输入
2
00000000000000000000000000000000
00000000000000000000000000000001
1
2
3
输出
00000000000000000000000000000001
00000000000000000000000000000011
00000000000000000000000000000010
000000000000000000000000000001
注意点:可能真的是太久没有打代码了....数据的输入方面如果不按下回车的话不管打多少字都是输入的一个变量,所以在接收字符方面是不能使用int num[32]作为数据的接收的。所以,在这道题中,数据的输入采用的 是string的形式,之后将string转化为了int型的字符串(使用string来接收数据并且实现各个位的分离是相当方便的,偶尔会设计到string和int类型之间的互转,直接调用C++库函数即可)。然后就是十进制与二进制的互转啦,这个比较简单。
// BYOJ1.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "iostream"
#include "math.h"
#include "string"
using namespace std;
int main()
{
int T;
cin >> T;
while (T--)
{
//实现对数据的接收
string snum;
cin >> snum;
int num[32]; int y = 0;
int ans1, ans2;
for (int i = 0; i < 32; i++) { num[i] = snum[i]-'0'; }
//将接受的数据转化为十进制
for (int i = 31; i >= 0; i--)
{
y += num[i] * pow(2, (31 - i));
}
ans1 = y + 1;
ans2 = y + 3;
//将十进制转化为二进制
int arr[32] = { 0 }, arr2[32] = { 0 };
int p = 31;
do
{
arr[p--] = ans1 % 2;
ans1 /= 2;
} while (ans1 != 0);
p = 31;
do
{
arr2[p--] = ans2 % 2;
ans2 /= 2;
} while (ans2 != 0);
//输出程序结果
for (int i = 0; i < 32; i++)
{
cout << arr[i];
}
cout << endl;
for (int i = 0; i < 32; i++)
{
cout << arr2[i];
}
cout << endl;
}
system("pause");
return 0;
}
第二题来自hihocoder 1081,主要思想是利用dijkstra求取不同单点到其他任意一点之间的最短距离。
坑:
- 由于题目中的节点是从1...N开始存储的,实际上对应着数组中的位置是0...N-1,直接差了一个1
- 这道题最坑也还是在题目的描述上(也是怪自己不好好读题),两点之间可能存在多个路径,并且把它作为无向图进行考虑,那么两点之间数据距离的存储就得讲究一些了,具体情况看代码
- D、P两个数组在没有确定源点之前需要初始化一次,在确定了源点之后依然要再进行更新
- 自己对dijkstra掌握的还是不够熟练吼,还是会丢一些比如flag[i]!=0之类的限制条件,在加入新顶点之后对其他路径的更新也是有点傻傻分不清楚,条件写着写着就有点乱了,最主要的锅还是因为算法思想没掌握熟练。总之总之,dijkstra的思想并不难,但是要正确的编程实现还是有很多很多需要注意的小细节,以后还是要多加训练啦~
// BYOJ1.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "iostream"
#include "math.h"
#include "string"
using namespace std;
int Graph[1001][1001];//矩阵大小待定,可能需要修改
int p[1001], d[1001], flag[1001] = { 0 }; //p数组记录相应的前驱结点(poinner),d数据记录距离,flag数组记录是否加入集合S中
int main()
{
//使用迪杰斯特拉算法求两点间的最短路径
//首先,实现对输入数据的接收,以邻接矩阵的形式存储
int n, m, s, t;//分别代表节点数、边数、两个结点
int loop; int i, j, length;
cin >> n >> m >> s >> t;
s -= 1;
t -= 1;
loop = m;
for (int u = 0; u < n; u++)
{
for (int v = 0; v < n; v++)
Graph[u][v] = 1002; //对邻接矩阵进行初始化
}
while (loop--) //更新地图中的数据,按照无向图进行考虑
{
cin >> i >> j >> length;//输入两条边长度及距离
if (length < Graph[i - 1][j - 1]) //行吧确实是个无向图两边都按最短的来
{
Graph[i - 1][j - 1] = length;
Graph[j - 1][i - 1] = length;
}
}
//使用迪杰斯特拉算法来求解最短路径问题
//对各个数组中的数据取值进行初始化
flag[s] = 1;//将起始结点加入S中
//对D、P在没有确定起始结点时进行更新
for (int i = 0; i < n; i++)
{
d[i] = 1002;
p[i] = -1;
}
//对D、P在确定起始结点之后又进行更新
for (int i = 0; i < n; i++)
{
d[i] = Graph[s][i];
//cout << "d[i]=" << d[i] << endl;
p[i] = s;
}
p[s] = -1;
//整个大循环要循环n-1次
loop = 0;
while (loop < n - 1)
{
//寻找当前d数组中的最小值
int min = 10001; int index;
for (int i = 0; i < n; i++)
{
//无论是寻找最小值的过程还是替换的过程都是在该点不在S集合的前提下进行的
if (flag[i]==0&&d[i] < min)
{
min = d[i];
index = i;
}
}
//cout << "min=" << min << endl;
//将这个值加入集合中
flag[index] = 1;//这意味着d[index]已经是最短路径了
//新加入这个值之后可能会对其他的路径产生影响
for (int i = 0; i < n; i++)
{ //从当前最短路径前i节点的距离如果小于原来到达i的距离,那么就进行更新
if (flag[i] == 0 && d[index] + Graph[index][i] < d[i])
{
d[i] = d[index] + Graph[index][i]; //更新距离及索引值
p[i] = index;
}
}
loop++;
}
//寻找当前节点到某一节点中的最小值
cout << d[t];
system("pause");
return 0;
}