A - The 3n+1 problem
题目背景就是著名的冰雹猜想,要求是给你两个数
a
,
b
a, b
a,b, 让你求
[
a
,
b
]
[a,b]
[a,b]中所有的数进行该猜想运算时最大的运算次数。题目数据较弱,直接暴力模拟计算过程即可(
P
S
:
PS:
PS:数组打表会RE, 且
a
,
b
a,b
a,b大小关系不定)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int a, b;
while (~scanf("%d %d", &a, &b)) {
cout << a << " " << b << " " ;
if (a > b) swap(a, b);
int ans = 0;
for (int i = a; i <= b; ++i) {
ll k = i;
int tmp = 1;
while (k != 1) {
if (k % 2 == 0) k /= 2;
else k = 3*k+1;
tmp++;
}
ans = max(ans, tmp);
}
cout << ans << '\n';
}
return 0;
}
B - Let’s Play Magic!
S
a
m
p
l
e
  
o
u
t
p
u
t
:
Sample\;output:
Sampleoutput:
Q
H
  
4
C
  
A
S
  
8
D
  
K
H
  
2
S
  
7
D
  
5
C
  
T
H
  
J
H
  
3
S
  
6
C
  
9
D
QH \; 4C \; AS \; 8D \; KH \; 2S \; 7D \; 5C \; TH \; JH \; 3S \; 6C \;9D
QH4CAS8DKH2S7D5CTHJH3S6C9D
- s t e p 1 step1 step1: 1, 2, 3 → \to → A S AS AS , 删除 A S AS AS \quad A C E = 3 ACE = 3 ACE=3
- s t e p 2 step2 step2: 1, 2, 3 → \to → 2 S 2S 2S,删除 2 S 2S 2S \quad T W O = 3 TWO = 3 TWO=3
- s t e p 3 step3 step3: 1, 2, 3, 4, 5 → \to → 3 S 3S 3S, 删除 3 S 3S 3S \quad T H R E E = 5 THREE = 5 THREE=5
- ⋯ \cdots ⋯
这题我们就是将
c
a
r
d
card
card逐次的插入,已插入的位置可以标记下来,有点像约瑟夫环的逆过程
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
string s1[maxn], s2[maxn];
int indexs[maxn];
int main()
{
int n;
while (~scanf("%d", &n), n) {
for (int i = 1; i <= n; ++i) {
cin >> s1[i] >> s2[i];
indexs[i] = -1;
}
for (int i = 1, j = 1; i <= n; ++i) {
for (int k = s2[i].size(); ; j = j%n + 1) {
if (indexs[j] == -1 && --k == 0) break;
}
indexs[j] = i;
}
for (int i = 1; i <= n; ++i) {
if (i != 1) cout << " " ;
cout << s1[indexs[i]] ;
}
cout << '\n';
}
return 0;
}
C - Cube painting
无论立方体如何旋转,对立面一定是不变的。通过前六个字符确定对立面之后,看旋转后的立方体的对立面与原先是否一样即可,注意顺序可能不同。
也可以把每个面旋转到第一个面,然后第一个面与它对应的面不动再进行四次旋转,判断。
AC代码:
#include <bits/stdc++.h>
using namespace std;
string s, str[3], cube, cube2;
int main()
{
while (getline(cin, s)) {
for (int i = 0; i < 3; ++i) str[i] = "";
str[0] += s[0];
str[1] += s[1];
str[2] += s[2];
str[0] += s[5];
str[1] += s[4];
str[2] += s[3];
cube = cube2 = "";
cube += s[6];
cube += s[11];
cube2 += s[11];
cube2 += s[6];
int i;
for (i = 0; i < 3; ++i) {
if (cube == str[i] || cube2 == str[i]) {
str[i] = "\0";
break;
}
}
if (i == 3) {
cout << "FALSE" << '\n';
continue;
}
cube = cube2 = "";
cube += s[7];
cube += s[10];
cube2 += s[10];
cube2 += s[7];
for (i = 0; i < 3; ++i) {
if (cube == str[i] || cube2 == str[i]) {
str[i] = "\0";
break;
}
}
if (i == 3) {
cout << "FALSE" << '\n';
continue;
}
cube = cube2 = "";
cube += s[8];
cube += s[9];
cube2 += s[9];
cube2 += s[8];
for (i = 0; i < 3; ++i) {
if (cube == str[i] || cube2 == str[i]) break;
}
if (i == 3) {
cout << "FALSE" << '\n';
continue;
}
cout << "TRUE" << '\n';
}
return 0;
}
D - A New Growth Industry
一个英语阅读题,题意是数组中的这个数和它上下左右四个数加起来的和对应在d表中能查到一个数,再把这个数和原来数组元素的相加 (大于3的为3,小于0的设为0.),最后根据对应符号输出
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--) {
int a[22][22] = {0};
int b[22][22] = {0};
int d[16];
int day;
char c[5] = {".!X#"};
scanf("%d", &day);
for(int i = 0; i < 16; ++i) scanf("%d",&d[i]);
for(int i = 1; i <= 20; ++i) {
for(int j = 1; j <= 20; ++j) scanf("%d", &a[i][j]);
}
while(day--) {
for(int i = 1; i <= 20; ++i) {
for(int j = 1; j <= 20; ++j) {
b[i][j] = a[i][j] + a[i-1][j] + a[i+1][j] + a[i][j-1] + a[i][j+1];
}
}
for(int i = 1; i <= 20; ++i) {
for(int j = 1; j <= 20; ++j) {
a[i][j] += d[b[i][j]];
if(a[i][j] > 3) a[i][j] = 3;
else if(a[i][j] < 0) a[i][j] = 0;
}
}
}
for(int i = 1; i <= 20; ++i) {
for(int j = 1; j <= 20; ++j) cout << c[a[i][j]];
cout << '\n';
}
if(T!=0) cout << '\n';
}
return 0;
}
E - Humble Numbers
质因子为2,3,5 or 7的数为
h
u
m
b
e
r
  
n
u
m
b
e
r
humber\;number
humbernumber, 对所有
h
u
m
b
l
e
  
n
u
m
b
e
r
humble\;number
humblenumber排序之后问你第几个数是多少
我们可以打表对2,3,5,7分别进行计算,每次只要让
a
[
i
]
a[i]
a[i]等于最小的那一个,再让其相应的倍数++
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a[5850];
void init()
{
a[1] = 1;
int x2 = 1, x3 = 1, x5 = 1, x7 = 1;
for (int i = 2; i <= 5845; ++i) {
a[i] = min(min(a[x2]*2, a[x3]*3), min(a[x5]*5, a[x7]*7));
if(a[i] == a[x2]*2) x2++;
if(a[i] == a[x3]*3) x3++;
if(a[i] == a[x5]*5) x5++;
if(a[i] == a[x7]*7) x7++;
}
}
int main()
{
init();
int n;
while(~scanf("%d",&n),n)
{
if(n % 100 == 11 || n%100 == 12 || n%100 == 13)
printf("The %dth humble number is %d.\n",n,a[n]);
else if(n%10 == 1)
printf("The %dst humble number is %d.\n",n,a[n]);
else if(n%10 == 2)
printf("The %dnd humble number is %d.\n",n,a[n]);
else if(n%10 == 3)
printf("The %drd humble number is %d.\n",n,a[n]);
else
printf("The %dth humble number is %d.\n",n,a[n]);
}
return 0;
}
F - hide handkerchief
有
n
n
n个圈围成环,从随机一点开始,每隔
m
−
1
m-1
m−1个圈涂一次色,问是否能将
n
n
n个圈全部染色
稍微造几个数据就能知道,如果
g
c
d
(
n
,
m
)
=
1
gcd(n, m) = 1
gcd(n,m)=1, 那么一定能在
n
n
n次下染色完成,若
g
c
d
(
n
,
m
)
  
!
=
1
gcd(n, m)\;!= 1
gcd(n,m)!=1, 那么一定会产生循环
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, m;
while (~scanf("%d %d", &n, &m)) {
if (n + m == -2) break;
if (__gcd(n, m) == 1) cout << "YES" << '\n';
else cout << "POOR Haha" << '\n';
}
return 0;
}
G - Robot Motion
建图之后,按照"N, S, E, W"方向按部就班的走就可以了,同时记录步数,在走过的位置vis标记,判断是否成环
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a,b,c;
char maps[15][15];
int vis[15][15];
void solve()
{
int x = 0, y = c-1;
int circle = 0, step = 0, step2 = 0;
vis[x][y] = 1;
while(1)
{
if(maps[x][y]== 'N') x--;
else if(maps[x][y] == 'W') y--;
else if(maps[x][y] == 'S') x++;
else if(maps[x][y] == 'E') y++;
if(y<0 || x<0 || x>=a || y>=b) break;
if(vis[x][y] == 0) {
vis[x][y] = 1;
step++;
}
else if(vis[x][y] == 1) {
vis[x][y] = 2;
step2++;
circle = 1;
}
else if(vis[x][y] == 2) break;
}
if(circle == 1) {
printf("%d step(s) before a loop of %d step(s)\n", step-step2+1, step2);
}
else printf("%d step(s) to exit\n", step+1);
}
int main()
{
while(~scanf("%d %d", &a, &b) && a+b) {
scanf("%d",&c);
memset(vis, 0, sizeof(vis));
for(int i = 0; i < a; ++i) scanf("%s", maps[i]);
solve();
}
return 0;
}
H - XK Segments
给你一个数组,问你满足
(
a
[
i
]
,
a
[
j
]
)
(a[i], a[j])
(a[i],a[j])中有
k
k
k个数为
x
x
x的倍数的组数有多少个
先排序,然后以
a
[
i
]
a[i]
a[i]为基准二分查找
a
[
j
]
a[j]
a[j]的位置,
l
e
f
t
=
(
a
[
i
]
−
a
[
i
]
%
x
)
+
k
x
left = (a[i]-a[i]\%x)+kx
left=(a[i]−a[i]%x)+kx,
r
i
g
h
t
=
l
e
f
t
+
x
right = left+x
right=left+x
注意这道题会爆int
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
ll a[maxn];
ll binary_searchs(ll l, ll r, ll key)
{
while(l <= r){
ll mid = (l+r)/2;
if(a[mid] >= key) r = mid-1;
else l = mid+1;
}
return l;
}
int main()
{
ll n, x, k;
cin >> n >> x >> k;
ll ans = 0;
for(ll i = 0; i < n; i++){
scanf("%lld", &a[i]);
}
sort(a, a+n);
for(ll i = 0; i < n; i++){
ll t = a[i]%x;
ll l = a[i] + (x-t) % x + (k-1)*x;
ll r = l + x;
if(!k){
l = a[i];
r = a[i] + (x-t)%x;
}
l = binary_searchs(0, n-1, l);
r = binary_searchs(0, n-1, r);
ans += r-l;
}
cout << ans << '\n';
return 0;
}
I - Funky Numbers
给你一个数
A
A
A, 问你是否存在
p
,
q
p,q
p,q 满足
A
=
p
(
p
+
1
)
2
+
q
(
q
+
1
)
2
A = \frac {p(p+1)}{2}+\frac{q(q+1)}{2}
A=2p(p+1)+2q(q+1)
依旧是遍历枚举
p
p
p,然后二分查找
q
q
q
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(~scanf("%d", &n)) {
int flag = 0;
for(int i = 1; i < sqrt(2*n); ++i) {
int p = i * (i+1) / 2;
int lf = i, rg = sqrt(2*n), mid = (lf + rg)/2;
while(lf <= rg) {
int q = mid * (mid+1) / 2;
if(p+q < n) lf = mid+1;
else if(p+q > n) rg = mid-1;
else {
flag = 1;
break;
}
mid = (lf + rg) / 2;
}
if(flag == 1) break;
}
if(flag == 1) cout << "YES" << '\n';
else cout << "NO" << '\n';
}
return 0;
}
J - Stairs and Elevators
首先,每个查询我们可以使用不超过一个楼梯或电梯。实际上,最佳路径始终是水平的几个部分,然后是电梯或楼梯,然后是水平的几个部分。
然后,我们总是可以使用最近的楼梯/电梯之一来开始/结束。因此,我们可以按照楼梯/电梯的顺序进行二分搜索以找到最佳的,并选择使用一个楼梯或电梯。不要忘记不必到达任何楼梯/电梯的情况。
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn], b[maxn];
int main()
{
int x, y, n, m, v;
cin >> x >> y >> n >> m >> v;
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
for (int i = 0; i < m; i++) scanf("%d", &b[i]);
int q;
cin >> q;
while (q--) {
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
if (y2 < y1) swap(y1, y2);
int c = lower_bound(a, a + n, y1) - a;
int ans = (int)1e9;
if (x1 == x2) ans = y2 - y1;
if (c < n)
ans = min(ans, abs(a[c] - y1) + abs(a[c] - y2) + abs(x1 - x2));
if (c > 0) {
c--;
ans = min(ans, abs(a[c] - y1) + abs(a[c] - y2) + abs(x1 - x2));
}
c = lower_bound(b, b + m, y2) - b;
if (c < m) {
ans = min(ans, abs(b[c] - y1) + abs(b[c] - y2) + (abs(x1 - x2) + v - 1) / v);
}
if (c > 0) {
c--;
ans = min(ans, abs(b[c] - y1) + abs(b[c] - y2) + (abs(x1 - x2) + v - 1) / v);
}
cout << ans << "\n";
}
return 0;
}