【HDOJ】2050 - 2059

引言:两年没写博客了,两年来经历了很多的事情,太多太多,无法说清(;′⌒`)。无论如何生活还要继续,当前计划从杭电OJ开始记录我的痕迹(ง •_•)ง。
(如有错误,欢迎指正o( ̄▽ ̄)ブ)

目录

  • 2050 (折线分割平面)
  • 2051 (Bitset)
  • 2052 (Picture)
  • 2053 (Switch Game)
  • 2054 (A == B ?)
  • 2055 (An easy problem)
  • 2056 (Rectangles)
  • 2057 (A + B Again)
  • 2058 (The sum problem)
  • 2059 (龟兔赛跑)

2050 (折线分割平面)

#include 
using namespace std;

int main() {
	int c, n;
	cin >> c;
	long long b[20001];
	b[1] = 2;
	for (int i = 2; i <= 20000; i++)
		b[i] = b[i - 1] + i;
	while (c--) {
		cin >> n;
		cout << b[2*n - 1] << endl;
	}
}

详细分析在这里:【HDOJ】2050 (折线分割平面)

2051 (Bitset)

#include 
#include 
using namespace std;

//用栈代替了递归的方式
int main() {
	int num;
	stack outPut;
	while (cin >> num) {
		while (num > 1) {
			outPut.push(num % 2);
			num /= 2;
		}
		if (num == 1) outPut.push(num);
		while (!outPut.empty()) {
			cout << outPut.top();
			outPut.pop();
		}
		cout << endl;
	}
}

2052 (Picture)

#include 
using namespace std;

int main() {
	int n, m;
	while (scanf("%d%d", &n, &m) != EOF) {
		cout << "+";
		for (int i = 1; i <= n; i++) cout << "-";
		cout << "+" << endl;

		for (int i = 1; i <= m; i++) {
			cout << "|";
			for (int j = 1; j <= n; j++) cout << " ";
			cout << "|" << endl;
		}

		cout << "+";
		for (int i = 1; i <= n; i++) cout << "-";
		cout << "+" << endl;
	}
}

2053 (Switch Game)

#include 
using namespace std;

//这道题的难点应该是看不太懂英文吧(;′⌒`)
int main() {
	int n;
	while (cin >> n) {
		int res = 0;
		for (int i = 1; i <= n; i++) {
			if (n % i == 0) res = res == 0 ? 1 : 0;
		}
		cout << res << endl;
	}
}

2054 (A == B ?)

#include 
#include 
using namespace std;

string dealNum(string num) {
	int i = 0, start = 0, len = num.size();
	if (len == 0) return "";

	//处理符号
	string op = "";
	if (num[0] == '+' || num[0] == '-') {
		i++;
		start++;
		len--;
		if (num[0] == '-') op = "-";
	}

	//处理整数前面的0
	while (i < num.size() && num[i] == '0') {
		i++;
		start++;
		len--;
	}

	//处理小数点后面的0
	bool isPoint = false;
	while (i < num.size()) {
		if (num[i] == '.') {
			isPoint = true;
			break;
		}
		i++;
	}
	if (isPoint) {
		i = num.size() - 1;
		while (num[i] == '0') {
			i--;
			len--;
		}
		if (num[i] == '.') {
			i--;
			len--;
		}
	}

	// 处理0
	if (len == 0) return "0";
	return op + num.substr(start, len);
}

int main() {
	string a, b;
	while (cin >> a >> b) {
		a = dealNum(a);
		b = dealNum(b);
		cout << (a == b ? "YES" : "NO") << endl;
	}
}

2055 (An easy problem)

#include 
using namespace std;

int main() {
	int len;
	cin >> len;
	char x;
	int y, res;
	while (len--) {
		cin >> x >> y;
		if (x >= 'A' && x <= 'Z') res = x - 'A' + 1 + y;
		else if (x >= 'a' && x <= 'z') res = y - (x - 'a' + 1);
		cout << res << endl;
	}
}

2056 (Rectangles)

#include 
#include 
using namespace std;

// --------------3       --------------1
// -   -         -       -   -         -
// -   -         -       -   -         -
// ------1       -       ------3       -
// -   2 ---------       -   0 ---------
// -     -       -       -     -       -
// 0--------------       2--------------
// 总是把(x1,y1)化成0的位置
// 总是把(x2,y2)化成1的位置
// 总是把(x3,y3)化成2的位置
// 总是把(x4,y4)化成3的位置
// 在矩阵相交的情况下,相交面积始终是第3大的坐标-第2大的坐标
int main() {
	double x1, y1, x2, y2, x3, y3, x4, y4;
	while (scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4) != EOF) {
		//处理矩形A的边界
		double a_left = min(x1, x2);
		double a_right = max(x1, x2);
		double a_bottom = min(y1, y2);
		double a_top = max(y1, y2);

		//处理矩形B的边界
		double b_left = min(x3, x4);
		double b_right = max(x3, x4);
		double b_bottom = min(y3, y4);
		double b_top = max(y3, y4);

		//计算相交区域的边界
		double overlap_left = max(a_left, b_left);
		double overlap_right = min(a_right, b_right);
		double overlap_bottom = max(a_bottom, b_bottom);
		double overlap_top = min(a_top, b_top);

		double res = 0;
		if (overlap_left < overlap_right && overlap_bottom < overlap_top) {
			res = (overlap_right - overlap_left) * (overlap_top - overlap_bottom);
		}
		printf("%.2lf\n", res);
	}
}

2057 (A + B Again)

#include 
using namespace std;

//这道题限制了a,b的长度,所以可以用长整形
//如果不限制a,b长度呢,我的方法是:解析字符,模拟计组那一套计算方式
int main() {
	long long a, b, res;
	//llx表示长整形的16进制形式,llX大写X表示十六进制大写
	while (scanf("%llx%llx", &a, &b) != EOF) {
		res = a + b;
		if (res < 0) {
			printf("-%llX\n", -res);
		}
		else {
			printf("%llX\n", res);
		}
	}
}

2058 (The sum problem)

#include 
using namespace std;

//本想着滑动窗口秒了,结果超时了
int main() {
	long long n, m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) break;

		long long left = 1, right = 1, target = 2 * m;
		while (left <= n && right <= n && left <= right) {
			if (left == m || right == m) {
				printf("[%lld,%lld]\n", m, m);
				break;
			}

			long long val = (left + right) * (right - left + 1);
			if (val == target) {
				printf("[%lld,%lld]\n", left, right);
				right++;
			}
			else if (val < target) right++;
			else left++;
		}
		printf("\n");
	}
}
#include 
using namespace std;

//优化算法
// (left + right) * (right - left + 1) = 2 * m ---- (首项+末项)*项数/2
// (2left + len - 1) * len = 2 * m ---- 求left, right
// => left = m / len + (1 - len) / 2
// => right = left + len - 1
// ---------------------------------
// (2left + len - 1) * len = 2 * m ---- 求len, left = 1时, len最大
// => (len + 1) * len = 2 * m
// => len * len < 2 * m
// => len < sqrl(2 * m)
int main() {
	long long n, m;
	while (cin >> n >> m) {
		if (n == 0 && m == 0) break;

		long long left, right, target = 2 * m;
		for (long long len = sqrt(target); len >= 1; len--) {
			left = m / len + (1 - len) / 2;
			right = left + len - 1;
			if ((left + right) * len == target)
				printf("[%lld,%lld]\n", left, right);
		}
		printf("\n");
	}
}

2059 (龟兔赛跑)

#include 
#include 
using namespace std;

//不能AC,因为到达一个充电站后,不同的剩余电量会影响最优路径的选择
//测试用例:
//40
//6 20 5
//5 8 2
//20 24 28 32 36 39
int main() {
	int l, n, c, t, vr, vt1, vt2, arr[102];
	double dp[102];
	while (cin >> l) {
		cin >> n >> c >> t >> vr >> vt1 >> vt2;
		arr[0] = 0;
		for (int i = 1; i <= n; i++) cin >> arr[i];
		arr[n + 1] = l;

		//乌龟到每一个点耗时
		dp[0] = 0;
		int rest_c = c;//剩余电力可以跑的距离
		for (int i = 1; i <= n + 1; i++) {
			int s = arr[i] - arr[i - 1];

			//剩余电力能跑到下一个充电站
			if (rest_c >= s) {
				rest_c -= s;
				dp[i] = dp[i - 1] + (double)s / vt1;
			}
			//剩余电力不能跑到下一个充电站
			//充电花的时间,和不充电花的时间,取最小值
			else {
				double time_no_charge, time_charge;
				int new_rest;

				//不充电花的时间
				time_no_charge = (double)rest_c / vt1 + (double)(s - rest_c) / vt2;

				//充满电后能够跑到下一个充电站
				if (c >= s) {
					new_rest = c - s;
					time_charge = (double)s / vt1 + t;
				}
				//充满电后也不能够跑到下一个充电站
				else {
					new_rest = 0;
					time_charge = (double)c / vt1 + (double)(s - c) / vt2 + t;
				}

				//不充电花的时间更多
				if (time_no_charge > time_charge) {
					rest_c = new_rest;
					dp[i] = dp[i - 1] + time_charge;
				}
				//充电花的时间更多
				else {
					rest_c = 0;
					dp[i] = dp[i - 1] + time_no_charge;
				}
			}
		}

		if (dp[n + 1] > ((double)l / vr)) cout << "Good job,rabbit!";
		else cout << "What a pity rabbit!";
	}
}
#include 
#include 
using namespace std;

// 由于之前最优路径的选择依赖于前一段路径
// 所以可以通过遍历前面所有路径,选出最短时间
int main() {
	int l, n, c, t, vr, vt1, vt2, arr[102];
	double dp[102];
	while (cin >> l) {
		cin >> n >> c >> t >> vr >> vt1 >> vt2;
		arr[0] = 0;
		for (int i = 1; i <= n; i++) cin >> arr[i];
		arr[n + 1] = l;

		//乌龟到每一个点耗时
		dp[0] = 0;
		for (int i = 1; i <= n + 1; i++) {
			dp[i] = -1;
			double time;
			//遍历前面每一个充电站,比较在那个充电站充电和不充电时,取花费的最小时间
			for (int j = 0; j < i; j++) {
				int s = arr[i] - arr[j];
				if (c >= s) time = dp[j] + (double)s / vt1;
				else time = dp[j] + (double)c / vt1 + (double)(s - c) / vt2;
				if (j > 0) time += t;
				if (dp[i] == -1) dp[i] = time;
				else dp[i] = min(dp[i], time);
			}
		}

		if (dp[n + 1] > ((double)l / vr)) cout << "Good job,rabbit!";
		else cout << "What a pity rabbit!";
	}
}

你可能感兴趣的:(杭电OJ,考研)