B----https://codeforces.com/contest/1872/problem/B
翻译:
你位于一个无限延伸向右的走廊中,走廊被分割成方形的房间。你从房间1出发,前往房间k,然后返回房间1。你可以选择k的值。移动到相邻的房间需要1秒。
此外,走廊中有n个陷阱:第i个陷阱位于房间di,并且在你进入房间di后si秒后被激活。一旦陷阱被激活,你就不能进入或离开带有该陷阱的房间。
请确定允许你从房间1前往房间k,然后安全返回房间1的最大值k。
例如,如果n=1,d1=2,s1=2,你可以前往k=2的房间并安全返回(陷阱将在时刻1+s1=1+2=3激活,它不能阻止你返回)。但是如果你尝试到达k=3的房间,陷阱将在时刻1+s1=1+2=3激活,阻止你返回(你将在第3秒尝试进入房间2,在此时陷阱已激活会阻止你)。任何更大的k值也不可行。因此,答案是k=2。
输入
输入的第一行包含一个整数t(1≤t≤1000)- 测试用例的数量。
接下来是每个测试用例的描述。
每个测试用例描述的第一行包含一个整数n(1≤n≤100)- 陷阱的数量。
接下来的n行每行包含两个整数di和si(1≤di,si≤200)- 陷阱的参数(你必须在进入该房间后的si秒内严格离开房间di)。可能有多个陷阱位于同一个房间(di的值可能重复)。
思想:简单来说,就是要考虑折返时间,我自己的想法实在是太复杂,而且也没做对。看了大佬的做法,实在的言简意赅,orzorz。只需要求出最小的折返距离即可。
AC代码
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n;
cin >> n;
int ans = 1 << 30;//2^30,无穷大
for (int i = 0, x, y; i < n; ++i) {
cin >> x >> y;
int move;
move = x + (y - 1) / 2;//计算这个房间能折返的最大距离
ans = min(ans, move);//选择最小的折返距离
}
cout << ans << endl;
}
int main() {
int t = 1;
cin >> t;
while (t--) {
solve();
}
}
E----Problem - E - Codeforces
翻译:
给出每个珊瑚的高度和最大的用水树,求出最大的墙的高度。
思想:我原来用的是一层一层的增加高度然后统计储水量,但最后TLE了。所以这题的话只能使用二分法的思想做。
AC代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
for (int i = 0; i < t; i++) {
int n, x;
cin >> n >> x;
vector<int> a(n);
for (int j = 0; j < n; j++) {
cin >> a[j];
}
long long tv = 0, fv = 4000000000;//fv选尽可能大的数就行
while (fv - tv > 1) {
long long mid = (tv + fv) / 2;
long long sum = 0;
for (int j = 0; j < n; j++) {
if(a[j]<mid) sum+=mid-a[j];
}
if (sum <= x) {
tv = mid;
}
else {
fv = mid;
}
}
cout << tv << endl;
}
}
C---C - 321-like Searcher
翻译:输出第k个类似“321”这样的倒序数字
思想:使用位运算生成了所有可能的 321-like 数字,然后对它们进行排序,并输出第 K 小的数字。
AC代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int K;
cin >> K;
vector<long long> A;
for (int i = 2; i < (1 << 10); i++) {
long long x = 0;
for (int j = 9; j >= 0; j--) {
if ((i >> j & 1) == 1) {
x = x * 10 + j;
}
}
A.push_back(x);
}
sort(A.begin(), A.end());
cout << A[K - 1] << endl;
}
蛇形填数
AC代码
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int dir[][2] = { {1,0},{0,-1},{-1,0},{0,1} };//顺时针方向
int main()
{
int n;
cin >> n;
int board[30][30] = { 0 };
int r = 1, c = n, d = 0;
for (int i = 1; i <= n * n; i++) {
board[r][c] = i;
int tr = r + dir[d][0];//继续当前方向
int tc = c + dir[d][1];
//判断当前方向是否越界,如果越界则改变方向(d改变)
if (tr > n || tr<1 || tc>n || tc < 1 || board[tr][tc]) d = (d + 1) % 4;
r += dir[d][0];//继续向前走
c += dir[d][1];
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
printf("%4d", board[i][j]);
}
if(i!=n) printf("\n");
}
return 0;
}