文章目录
A. Marathon
思路:将
a
n
s
ans
ans 初始化为
3
3
3,剩下三个数跟第一个数比,若第一个数比剩下的数大则 ans --
,最终剩下的数即为答案!
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
int T;
cin >> T;
while (T -- )
{
int a, b, c, d;
cin >> a >> b >> c >> d;
int ans = 3;
if (a > b) ans -- ;
if (a > c) ans -- ;
if (a > d) ans -- ;
cout << ans << endl;
}
return 0;
}
B. All Distinct
思路:我们可以用 s e t set set 将数组内的元素去重,故设数组的大小为 n n n,所有出现过元素所构成的集合的大小是 s e t . s i z e ( ) set.size() set.size(),那么所有重复元素所构成集合的大小为 n − s e t . s i z e ( ) n-set.size() n−set.size(),我们可以不断的在所有重复元素所构成集合中一直消去两个元素,直到该集合内的元素为 0 0 0。此时我们开始分类讨论:
- 当 n − s e t . s i z e ( ) n-set.size() % 2 = 0 n−set.size() 时,此时可以说明所有重复元素所构成集合中的元素刚好可以被消耗殆尽,此时答案就是 s e t . s i z e ( ) set.size() set.size()。
- 当 n − s e t . s i z e ( ) n-set.size() % 2 = 1 n−set.size() 时,此时可以说明所有重复元素所构成集合中的元素被消耗殆尽时,还要添上1个才能使得被变化的集合中无重复元素,所以答案就是 s e t . s i z e ( ) − 1 set.size()-1 set.size()−1。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
int main()
{
int T;
cin >> T;
while (T -- )
{
int n;
cin >> n;
set<int> s;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
s.insert(x);
}
if ((n - s.size()) % 2 == 0)
cout << s.size() << endl;
else
cout << s.size() - 1 << endl;
}
return 0;
}
C.Where’s the Bishop?
思路:反正图也不大,直接遍历一下全图,找一下该点的四个方位是否都是#
,若是则该位置就是答案,返回这个位置的下表即可!
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10;
char g[N][N];
int res[2];
int dx[4] = {1, 1, -1, -1}, dy[4] = {1, -1, 1, -1};
void bfs()
{
for (int i = 0; i < 8; i ++ )
for (int j = 0; j < 8; j ++ )
{
bool flag = false;
for (int k = 0; k < 4; k ++ )
{
int x = i + dx[k], y = j + dy[k];
if (x >= 0 && x < 8 && y >= 0 && y < 8)
{
if (g[x][y] != '#')
{
flag = true;
break;
}
}
else
{
flag = true;
break;
}
}
if (!flag)
{
res[0] = i, res[1] = j;
return;
}
}
}
int main()
{
int T;
cin >> T;
while (T -- )
{
for (int i = 0; i < 8; i ++ )
for (int j = 0; j < 8; j ++ )
cin >> g[i][j];
bfs();
cout << res[0] + 1 << " " << res[1] + 1 << endl;
}
return 0;
}
D. The Clock
思路:把所有数全部化成分钟,然后预处理一下从0~1439中所有的回文时间,最后以 x x x 为偏移量,以所给的开始时间为初始时间,直到第二次循环到开始时间的时候停止,统计一下这段时间内的回文时间!
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
set<int> s;
void init()
{
for (int i = 0; i < 1440; i ++ )
{
int m = i % 60;
int n = i / 60;
string str1 = to_string(n);
string str2 = to_string(m);
if (n < 10)
str1 = "0" + str1;
if (m < 10)
str2 = "0" + str2;
if (str1[0] == str2[1] && str1[1] == str2[0])
s.insert(i);
}
}
int main()
{
int n;
cin >> n;
init();
while (n -- )
{
string str;
int x;
cin >> str >> x;
int ans = 0;
int m = ((str[0] - '0') * 10 + (str[1] - '0')) * 60 + (str[3] - '0') * 10 + (str[4] - '0');
bool flag = false;
for (int i = m; ; i += x)
{
i = i % 1440;
if (flag && i == m)
break;
flag = true;
if (s.count(i))
ans ++ ;
}
cout << ans << endl;
}
return 0;
}
E.Binary Deque
思路:对于该题目来说我们只需要采用双指针,找出最长包含 s s s 个1的子序列,最终答案就是总长度-最长包含 s s s 个1的子序列的长度。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
int main()
{
int T;
cin >> T;
while (T -- )
{
int n, x;
int a[N];
cin >> n >> x;
int sum = 0;
int s = 0;
for (int i = 0; i < n; i ++ )
{
cin >> a[i];
s += a[i];
}
if (s < x)
cout << -1 << endl;
else
{
int l = 0, ans = 0;
for (int i = 0, j = 0; j < n; j ++ )
{
sum += a[j];
if (sum == x)
l = j - i + 1;
if (sum > x)
{
while (a[i] != 1) i ++ ;
sum -- ;
i ++ ;
}
ans = max(ans, l);
}
cout << n - ans << endl;
}
}
return 0;
}
F.3SUM
思路:
-
先进行初始化操作,将所有可能构成尾数为 3 3 3 的3个数变为字符串送入set中。
-
然后将所有数的最后一位截取出来送入 a a a 数组里面(这样可保证所有数字都在0~9这个区间上),且保证 a a a 数组里面相同的数字不超过 3 3 3 个(因为在0~9这个区间内,最多可以凑出3,13,23这三个数字,凑出3只需要最多3个1,凑出13也最多只需要2个相同的数,凑出23也最多只需要2个相同的数,至此我们就把整个数组的范围压缩到27以内!)
-
最后三层遍历看一下这三组所构成的字符串在不在set中,如果在则直接输出
YES
,若遍历完整个数组都没有的话,则输出NO
。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
using namespace std;
set<string> s;
void init()
{
for (int i = 0; i < 10; i ++ )
for (int j = i; j < 10; j ++ )
for (int k = j; k < 10; k ++ )
if (i + j + k == 3 || i + j + k == 13 || i + j + k == 23)
s.insert(to_string(i) + to_string(j) + to_string(k));
}
int main()
{
int T;
cin >> T;
init();
while (T -- )
{
int n;
string str;
vector<int> a;
cin >> n;
map<int, int> m;
while (n -- )
{
cin >> str;
int x = str[str.size() - 1] - '0';
if (m[x] < 3)
{
a.push_back(x);
m[x] ++ ;
}
}
sort(a.begin(), a.end());
bool flag = false;
int size = a.size();
for (int i = 0; i < size; i ++ )
for (int j = i + 1; j < size; j ++ )
for (int k = j + 1; k < size; k ++ )
{
string ss = to_string(a[i]) + to_string(a[j]) + to_string(a[k]);
if (s.count(ss))
{
flag = true;
break;
}
}
if (!flag)
puts("NO");
else
puts("YES");
}
return 0;
}
G.2^Sort
思路:
- 我们只需要额外开辟一个
b
b
b 数组,来记录是否
a[i] < a[i + 1] * 2
。 - 然后从0到 k k k 将所有的 b b b 数组元素加起来,记做 s u m sum sum。
- 若
sum == k
,则答案ans ++
。 - 然后再次从
k
k
k 开始到
n
−
1
n - 1
n−1,每一次
s
u
m
sum
sum 加上当前的
b
b
b,然后再减去
k
k
k 之前的
b
b
b ,若
sum == k
的话,则答案ans ++
。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int main()
{
int T;
cin >> T;
while (T -- )
{
int n, k;
cin >> n >> k;
int a[N], b[N];
for (int i = 0; i < n; i ++ ) cin >> a[i];
for (int i = 0; i < n; i ++ ) b[i] = (a[i] < a[i + 1] * 2);
int sum = 0;
int res = 0;
for (int i = 0; i < k; i ++ ) sum += b[i];
if (sum == k) res ++ ;
for (int i = k; i < n - 1; i ++ )
{
sum += b[i];
sum -= b[i - k];
if (sum == k) res ++ ;
}
cout << res << endl;
}
return 0;
}
H.Gambling
思路:即找出一个区间使得众数的个数要比非众数的个数要大
- 先将所有相同的数字的下标存入一个数组中去。
- 然后遍历一下每个元素所存入的数组 a a a,算出在数组 a a a 中,值为 x x x 的元素减去值不为 x x x 元素的差,即 i − j + 1 − ( a i − a j − ( i − j + 1 ) ) i-j+1-(a_i-a_j-(i - j + 1)) i−j+1−(ai−aj−(i−j+1)),我们整理一下 2 i − a i − 1 + a j − 2 j 2i-a_i-1+a_j-2j 2i−ai−1+aj−2j,不变的是 2 i − a i − 1 2i-a_i-1 2i−ai−1,变化的是 a j − 2 j a_j-2j aj−2j我们记为 t t t 最后使得 t t t 最大,顺便记录一下左端点 a i a_i ai。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
int main()
{
int T;
cin >> T;
while (T -- )
{
int n;
cin >> n;
map<int, vector<int>> m;
for (int i = 1; i <= n; i ++ )
{
int x;
cin >> x;
m[x].push_back(i);
}
int mx = 0, ans, l, r;
for (auto &[x, a] : m)
{
int t = -1e9, pos;
for (int i = 0; i < a.size(); i ++ )
{
if (a[i] - 2 * i > t)
t = a[i] - 2 * i, pos = a[i];
int now = 2 * i - a[i] + t + 1;
if (now > mx)
mx = now, ans = x, l = pos, r = a[i];
}
}
cout << ans << " " << l << " " << r << endl;
}
return 0;
}