A. Marathon
题意:四个人在马拉松比赛中分别跑了 a,b,c,d 米,保证四个数两两不同,问比第一个人(跑 a 米的那个)跑得更远的人有几个。
思路:模拟即可
int a, b , c , d;
cin >>a >> b >>c >>d;
int cnt = 0;
if(b >a)cnt++;
if(c >a)cnt++;
if(d >a)cnt ++;
cout <<cnt << endl;
B. All Distinct
题意:有多组数据。 给你若干个数,每次删除 2 个数,求删除若干次后使数中没有重复的前提下剩下最长的长度
思路:题意比较抽象,可以理解为:每次操作可以删除两个数,求经过任意次操作后,剩下的序列没有相同的元素,求剩下的序列的最长的长度
我们可以发现,每次会删除两个数,最后剩下两种情况:
1:还剩一对相同的
2:一对不剩
然后记录一下能删除多少,模拟即可
// Code Start Here
int t;
cin >> t;
while(t--){
int n;
cin >> n;
vector<int> a(n);
map<int,int> mp;
for(int i = 0;i<n;i++){
cin >>a[i];
mp[a[i]]++;
}
int cnt = 0;
for(auto [k,v] : mp){
if(v > 1){
cnt += v - 1;
}
}
if(cnt % 2 & 1)cout << sz(mp) - 1 << endl;
else cout << sz(mp) << endl;
}
C. Where's the Bishop?
题意:
有一个8×8的棋盘,列编号从左到右递增,行编号从上到下递增。
给出一个棋盘,上面用#标明了主教的攻击范围。请你找出主教的位置坐标,并输出其行、列编号。
保证:主教的行、列编号均在2与7之间。
思路:明显要符合国际象棋象的走法,左上右上左下右下都要是#,模拟即可
string c[10];
for(int i=0;i<8;++i) cin>>c[i];
for(int i=1;i<7;++i){//遍历数组
for(int j=1;j<7;++j){
if(c[i][j]=='#'&&c[i-1][j-1]=='#'&&c[i-1][j+1]=='#'&&c[i+1][j-1]=='#'&&c[i+1][j+1]=='#'){
cout<<i+1<<" "<<j+1<<"\n";
return;
}
}
}
D. The Clock
题意:
从一个24小时制的时间点开始,每隔 x 分钟看一次手表,求到重新看到此时间点为止一共看到了多少个回文时间点。
回文时间点:诸如13:31,25:52等时间点。
思路:我们可以发现过了 3600 次 x 秒后,当前的时间就一定与原来输入的时间一致,形成循环。
因此枚举每一个可能的时间,判断即可。
int t;
int sh,sm,x;
cin >> t;
while(t--){
scanf("%2d:%2d\n",&sh,&sm);
cin >> x;
int nh=sh,nm=sm;
int ans=0;
for(int i=1;i<=3600;i++){
nm+=x;
if(nm>=60){
nh+=nm/60;
nm%=60;
}
if(nh>=24){
nh%=24;
}
if(nh/10==nm%10&&nh%10==nm/10){
ans++;
}
if(nh==sh&&nm==sm){
break;
}
}
cout << ans << endl;
}
return 0;
}
E. Binary Deque
题意:
有多组数据。每组数据给出 n 个数,每个数为 0 或 1 。你可以选择从两边删数,求至少删几个数才可以使剩下的数总和为 s 。如果不能达到 s ,则输出 −1 。
思路:很明显的,数组本身的和小于s,肯定无解
我们可以把剩下的记录成这样一个模型:可以采取类似前缀和的方式,然后双指针计算l ~ r之间的和,如果小则r ++大则l++,相等则实时更新答案。
// Code Start Here
int t;
cin >> t;
while(t--){
int n , s;
cin >> n >> s;
vector<int> a(n);
int sum = 0;
for(int i = 0;i<n;i++){
cin >> a[i];
sum += a[i];
}
int l = 0,r = 0;
int ans = INF;
if(sum <s)cout <<"-1\n";
else{
sum = a[0];
while(l < n && r <n){
if(sum == s){
ans = min(n + l - r - 1,ans);
r ++;
sum += a[r];
}
else if(sum > s){
sum -= a[l];
l++;
}
else{
r++;
sum += a[r];
}
}
cout << ans << endl;
}
}
F. 3SUM
题意:
给出一个长度为 n 的正整数数组 a,判断是否存在三个不同的下标 i,j,k,使 ai+aj+ak以数字 3 结尾。
思路:看末尾数字相加 = 3即可,很容易联想到遍历一下末尾数字都有哪些,然后组合一下,能形成3则Yes。
更具体的,可以开一个数组来记录出现次数,然后遍历即可
// Code Start Here
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int>a(n + 1, 0);
vector<int> cnt(11, 0);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
++cnt[a[i] % 10];
}
bool f = false;
for (int i = 0; i <= 9; ++i) {
for (int j = i; j <= 9; ++j) {
for (int k = j; k <= 9; ++k) {
if ((i + j + k) % 10 - 3) continue;
--cnt[i], --cnt[j], --cnt[k];
if (cnt[i] >= 0 && cnt[j] >= 0 && cnt[k] >= 0) {
f = true;
}
++cnt[i], ++cnt[j], ++cnt[k];
}
}
}
if (f)cout << "Yes\n";
else cout << "No\n";
}
G. 2^Sort
题意:
给你一个长度为 n (∑n<2⋅105) 的数组 a,问你在这个数组中,有多少个长度为 k+1 (1≤k<n) 的区间,符合以下的条件:
2^0⋅a_i < 2^1⋅a_i+1 < 2^2⋅a_i+2 < ⋯ < 2^k⋅a_i+k
思路:
观察到原不等式满足这样一个关系:
a_i < a_i+1 *2
所以即求最长一段子区间是否满足题意即可
// Code Start Here
int t;
cin >> t;
while (t--) {
int n , x;
cin >> n >>x;
vector<int> a(n+1);
vector<int> b(n+1,0);
for(int i = 1;i<=n;i++)cin >> a[i];
for(int i = 1;i<n;i++){
if(a[i] >= a[i+1] * 2){
b[i] = -1;
}
}
b[n] = -1;
int now = 0,ans = 0;
for(int i = 1;i<=n;i++){
if(b[i] == 0)now++;
else{
if(now >= x){
ans += now - x + 1;
}
now = 0;
}
}
cout << ans << endl;
}
H. Gambling
题意:
Marian 在一个赌场,赌场的游戏规则如下:
每一轮开始前,玩家选一个在 1 到 1e9 。然后,掷出一个有着 1e9 面的骰子,会随机出现一个在 1 与 1e9 之间的数。如果玩家猜对了,他们的钱就会翻一番,否则他们的钱会被折半。
Marian 可以预测未来,他知道在接下来 n 轮里骰子上的数,即 x1,x2,...,xn。
Marian 会选择三个整数 a,l 和 r(l≤r)。他会玩 r−l+1 轮。每一轮,他都猜同一个数 a。一开始(在第 l 轮之前)他有 1 美元。
Marian 请你帮助他决定 a,l 和 r(1≤a≤1e9,1≤l≤r≤n),让他最后的钱最多。
思路:观察到每次猜对数字都会翻倍,显然要在某个区间之内猜对最多,猜错少,然后最大化猜对-猜错的次数。
于是可以建立模型:给定数组 x[] 和 n,求出数组中的一个值 a 和区间 [l,r],使得在区间 [l,r] 中等于 a 的值和不等于 a 的值得个数的差最大。
观察到数组范围很大,需要离散化,于是开一个map<int,vector<int>>记录即可
// Code Start Here
int t;
cin >> t;
while (t--) {
map<int, vector<int >> mp;
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
mp[a[i]].push_back(i);
}
int ans = 1;
int max_val = a[1], ans_l = 1, ans_r = 1;
for (auto [num, vec] : mp) {
int cnt = 1;
int frt = vec[0],lst = vec[0];
int now_val = num;
for (int j = 1; j < sz(vec); j++) {
cnt -= (vec[j] - lst - 2);
if (cnt <= 0) cnt = 1, frt = vec[j];
if (cnt > ans) {
ans_l = frt;
ans_r = vec[j];
ans = cnt;
max_val = now_val;
}
lst = vec[j];
}
}
cout << max_val << " " << ans_l << " " << ans_r << endl;
}
491

被折叠的 条评论
为什么被折叠?



