思路:将 a n s ans ans 初始化为 3 3 3,剩下三个数跟第一个数比,若第一个数比剩下的数大则 ans --
,最终剩下的数即为答案!
Code:
#include
#include
#include
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;
}
思路:我们可以用 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。此时我们开始分类讨论:
Code:
#include
#include
#include
#include
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;
}
思路:反正图也不大,直接遍历一下全图,找一下该点的四个方位是否都是#
,若是则该位置就是答案,返回这个位置的下表即可!
Code:
#include
#include
#include
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;
}
思路:把所有数全部化成分钟,然后预处理一下从0~1439中所有的回文时间,最后以 x x x 为偏移量,以所给的开始时间为初始时间,直到第二次循环到开始时间的时候停止,统计一下这段时间内的回文时间!
Code:
#include
#include
#include
#include
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;
}
思路:对于该题目来说我们只需要采用双指针,找出最长包含 s s s 个1的子序列,最终答案就是总长度-最长包含 s s s 个1的子序列的长度。
Code:
#include
#include
#include
#include
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;
}
思路:
先进行初始化操作,将所有可能构成尾数为 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
#include
#include
#include
#include
#include
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;
}
思路:
a[i] < a[i + 1] * 2
。sum == k
,则答案 ans ++
。sum == k
的话,则答案 ans ++
。Code:
#include
#include
#include
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;
}
思路:即找出一个区间使得众数的个数要比非众数的个数要大
Code:
#include
#include
#include
#include
#include
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;
}