2025牛客寒假算法基础集训营6
A.复制鸡
思路:比较简单,略。
void solve()
{
int n, m, k;
cin >> n;
int last = -1, ans = 0;
for (int i = 0; i<n; i++){
int x;
cin >> x;
if (x != last){
ans++;
}
last = x;
}
cout << ans << endl;
}
B.好伙计猜拳
思路:这道题和最长子序列相似,在符合时加1,而这里是加惩罚值,并且又有交换的条件,所以开二维数组来进行动态转移。
void solve()
{
int n, c1, c2;
cin >> n >> c1 >> c2;
vector<int> a(n+1), b(n+1);
for (int i = 1; i<=n; i++){
cin >> a[i] >> b[i];
}
vector<vector<int>> dp(n+1, vector<int>(2, INF));
dp[0][0] = 0;
int ans = INF;
for (int i = 1; i<=n; i++){
for (int j = 0; j<i; j++){
if (a[j] <= a[i] && b[j] <= b[i]) // (aj, bj) -> (ai, bi)
dp[i][0] = min(dp[i][0], dp[j][0]+c1*(i-j-1));
if (a[j] <= b[i] && b[j] <= a[i]) // (bj, aj) -> (ai, bi)
dp[i][0] = min(dp[i][0], dp[j][1]+c1*(i-j-1));
}
for (int j = 0; j<i; j++){
if (a[j] <= b[i] && b[j] <= a[i]) // (aj, bj) -> (bi, ai)
dp[i][1] = min(dp[i][1], dp[j][0]+c1*(i-j-1));
if (b[j] <= b[i] && a[j] <= a[i]) // (bj, aj) -> (bi, ai)
dp[i][1] = min(dp[i][1], dp[j][1]+c1*(i-j-1));
}
dp[i][1] += c2;
ans = min({ans, dp[i][0]+c1*(n-i), dp[i][1]+c1*(n-i)});
}
cout << ans << endl;
}
C.数列之和
思路:这道题可以打表观察出来规律,之前以为会是加2和加4的规律,发现并没有什么规律,再仔细观察,查看缺失值是哪些,发现是,所以就简单了,二分一下就能做出来,并注意二分的左右取值,1e18大概是
,以为k的范围到1e18,其中并不可能缺失一半,所以假设k的范围为2e18,所以来确定取值,如果取值太大后对2取指数会超范围。
int qpow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res *= a) ;
a *= a ;
b >>= 1;
}
return res;
}
void solve()
{
int n, m, k;
cin >> n;
if (n == 1){
cout << 2 << endl;
return ;
}
auto check = [&](int x)->bool
{
int p = qpow(2, x);
return p/2-(x-1) >= n;
};
int l = 0, r = 125;
while (l+1 < r){
int mid = (l+r) >> 1;
if (check(mid)) r = mid;
else l = mid;
}
cout << 2*(r+n-2) << endl;
}
F.薪得体会
void solve()
{
int n, m, k;
cin >> n;
vector<node> s(n+1);
for (int i = 1; i<=n; i++){
cin >> s[i].a >> s[i].b;
s[i].sum = s[i].a + s[i].b;
}
int ans = 0;
sort(s.begin()+1, s.end(), [&](node x, node y){
return x.sum < y.sum;
});
vector<int> mx(n+1);
for (int i = 1; i<=n; i++) mx[i] = max(mx[i-1], s[i].a+s[i].b);
for (int i = 1; i<=n; i++){
if (ans >= s[i].a) ans = max(ans, s[i].sum);
else ans = max(ans, s[i-1].sum);
ans = max(ans, s[i].a);
}
cout << ans << endl;
}
H.小鸡的排列构造
void solve()
{
int n, m;
cin >> n >> m;
int l, r, c;
for (int i = 0; i<m; i++){
cin >> l >> r >> c;
}
if ((l-r+1) % 2 == 0){
for (int i = n; i>=1; i--){
cout << i << " \n"[i==1];
}
return ;
}
else{
vector<int> a(n+1);
iota(a.begin()+1, a.end(), 1);
sort(a.begin()+1, a.end(), greater<int>());
for (int i=n; i>=2; i-=2){
swap(a[i], a[i-1]);
}
for (int i = 1; i<=n; i++){
cout << a[i] << " \n"[i==n];
}
}
}
I.小鸡的排列构造的checker
struct query{
int l, r, c;
};
class Fenwick{
public:
vector <int> tree;
int n;
Fenwick (){}
Fenwick (int x){
init(x);
}
void init(int x){
n = x;
tree.resize(n + 1);
}
int lowbit(int x){
return x & (-x);
}
void add(int x, int k){
for(; x <= n; x += lowbit(x))
tree[x] += k;
}
int qsum(int x){
int ans = 0;
for(; x; x -= lowbit(x))
ans += tree[x];
return ans;
}
void clean(){
for(int i = 1; i <= n; i ++) tree[i] = 0;
}
};
void solve()
{
int n, m, k;
cin >> n >> m;
Fenwick fen(n);
vector<int> pos(n+1), val(n+1);
for (int i = 1; i <= n; i++) {
cin >> val[i];
pos[val[i]] = i;
}
vector<query> que(m+1);
vector<vector<int>> q(n+1);
for (int i = 0; i<m; i++){
cin >> que[i].l >> que[i].r >> que[i].c;
q[val[que[i].c]].push_back(i);
}
vector<int> ans(m);
for (int i = 1; i<=n; i++){
for (int j: q[i]) ans[j] = fen.qsum(que[j].r)-fen.qsum(que[j].l-1)+que[j].l;
fen.add(pos[i], 1);
}
for (int i=0; i<m; i++){
cout << ans[i] << "\n";
}
}
J.铁刀磨成针
void solve()
{
int n, x, y;
cin >>n >> x >> y;
auto dc = [&](int s, int xs)->int
{
int res = (s+(s-xs+1))*xs/2;
return res;
};
int ans = 0;
for (int i = 1; i<=min(n, y); i++){
int now = x+i;
int sum = now*(min(n, y)-i);
sum += dc(now, min(now, n-min(n, y)+1));
ans = max(ans, sum);
}
cout << ans << endl;
}
K.鸡翻题
void solve()
{
int n, x, y;
cin >> x >> y;
if (y % 2 == 0){
cout << "NO" << endl;
return ;
}
if (x % 2 == 0){
if (y % 4 == 1){
cout << "YES" << endl;
return ;
}
else {
cout << "NO" << endl;
return ;
}
}
else {
if (y % 4 == 3){
cout << "YES" << endl;
return ;
}
else {
cout << "NO" << endl;
return ;
}
}
}
L.变鸡器
void solve()
{
int n, m, k;
cin >> n;
string s, st = "CHICKEN";
cin >> s;
map<char, int> mp;
mp['C'] = -2, mp['H'] = -1, mp['I'] = -1, mp['K']=-1, mp['E']=-1, mp['N'] = -1;
int num = 0;
for (int i = 0; i<n; i++){
if (s[i] == st[num]) num++;
mp[s[i]]++;
}
if (num != 7){
cout << "NO" << endl;
return ;
}
if ((n-num)%2){
cout << "NO" << endl;
return ;
}
vector<int> sb;
for (auto [x, nn] : mp){
sb.push_back(nn);
}
int max_num = *max_element(sb.begin(), sb.end());
int sum = accumulate(sb.begin(), sb.end(), 0ll);
if (max_num <= sum/2){
cout << "YES" << endl;
}
else cout << "NO" << endl;
}