牛客周赛round91
C
若序列为1 4 5 7 9 1 2 3,1 + 9一定大于1 + 1或1 + 4...所以只需要记录当前数之前数字的最大值,然后遍历取max即可,所以对于上面的序列有效的比较为1 + 9,2 + 9,3 + 9取max
代码
//求大于当前数的最大值,然后取min即可
#include<bits/stdc++.h>using namespace std;const int N = 2e5 + 10;
int a[N], mi[N];int T, n;
int main()
{cin >> T;while(T -- ){int ans = -1;cin >> n;for(int i = 1; i <= n; i ++){cin >> a[i], mi[i] = max(a[i], mi[i - 1]);}for(int i = n; i >= 1; i --){if(mi[i - 1] > a[i])ans = max(ans, mi[i - 1] + a[i]);}//for(int i = 1; i <= n; i ++) cout << mi[i] << ' ';if(ans == -1) cout << "0" << endl;else cout << ans << endl;}return 0;
}
D
排序后寻找连续自然数的段数,答案就是段数-1
注意,当出现1 3 3 3 3 5 6 7,虽然自然数的段数为3,但是第二个段3 3 3 3前后都无绝对值之差为1的自然数,那么3 3 3 3的内部就需要互相连接才能保证与前后两个段内的数进行互相连通,则答案为3(段数) + 3(内部相连) - 1(三段只需要两条边即可互相连通)
对于1 3 4 4 4 6 7,其中的每一个4都可以借助3与1进行互相连通,也可以借助最后一个4与6进行互相连通
代码:
#include<bits/stdc++.h>using namespace std;//选用map的好处,可以记录当前数字的个数,也等于变相去重
map<int, int> mp;
int t;
int n;void solve()
{cin >> n;mp.clear();for(int i = 0; i < n; i ++){int x;cin >> x;mp[x] ++;}int ans = -1;for(auto & t : mp){int x = t.first, y = t.second;if(mp[x - 1] == 0)//当前数的前一个数不存在,则为一个单独的段,答案+1{ans ++;if(mp[x - 1] == 0 && mp[x + 1] == 0)//前后都不存在,则该数字内部需要互相连通ans += y - 1;}}cout << ans << endl;
}int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> t;while(t -- )solve();return 0;
}
E
四种情况
1、只有两行全为1
2、只有两列全为1
3、一行一列全为1且交叉点为0
4、全为0
对上面四种情况分类讨论即可,列出了一些简单样例
代码:
#include<bits/stdc++.h>using namespace std;const int N = 1050;
int t;
map<int, int> mpx, mpy;//记录每行以及每列中1的个数
int a[N][N];void solve()
{int n, m, ans = 0;memset(a, 0, sizeof a);mpx.clear(), mpy.clear();cin >> n >> m;for(int i = 0; i < n; i ++){string ch;//注意输入格式,每行输入为字符串cin >> ch;for(int j = 0; j < ch.size(); j ++){a[i][j] = (ch[j] == '1'? 1: 0);if(a[i][j]){ans ++;//记录总体1的个数mpx[i] ++, mpy[j] ++;}}}bool st = true, sti = false, stj = false, stij = false;//若有两行满足全为1int mx = 0, my = 0, mxy = 0;for(int i = 0; i < n; i ++) if(mpx[i] == m)mx ++;//只有仅有两行全为1时才满足条件,则此时所有1的个数应等于两行1的个数sti = (mx == 2 && mx*m == ans ? true : false);//若有两列满足全为1for(int j = 0; j < m; j ++)if(mpy[j] == n)my ++;stj = (my == 2 && my*n == ans ? true : false);//同理int cnt = 0;//记录一行一列时1的个数for(int i = 0; i < n; i ++)for(int j = 0; j < m; j ++){if(a[i][j] == 1) st = false;if(mpx[i] == m - 1 && mpy[j] == n - 1 && a[i][j] == 0){mxy ++;cnt += mpx[i] + mpy[j];}}//仅有一行一列满足,无其他情况stij = (mxy == 1 && cnt == ans? true : false);//四类满足一种即可if(sti || stj || stij || st) puts("YES");else puts("NO");return;
}int main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> t;while(t -- )solve();return 0;
}
f等待补题ing