您的位置:首页 > 游戏 > 游戏 > 开发公司公司简介_招聘58同城找工作_市场营销策划案的范文_教育培训机构排名前十

开发公司公司简介_招聘58同城找工作_市场营销策划案的范文_教育培训机构排名前十

2025/5/1 8:33:50 来源:https://blog.csdn.net/2401_88501775/article/details/147632492  浏览:    关键词:开发公司公司简介_招聘58同城找工作_市场营销策划案的范文_教育培训机构排名前十
开发公司公司简介_招聘58同城找工作_市场营销策划案的范文_教育培训机构排名前十

B.Binary Typewriter

在这里插入图片描述

思路

  • 至多使用1次操作,考虑1次操作的效果。
  • 发现,1次操作可以使得0和1更连贯,减少切换0/1导致的操作数
  • 最多减少两次操作

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n;string s;cin >> n >> s;s = "0" + s;bool op = 0;int ans = 0;for(int i = 1; i <= n; i ++){if(op != s[i] - '0'){op = !op;ans ++;}ans ++;}int j1 = -1;for(int i = 1; i <= n; i ++){if(s[i] == '1'){j1 = i;break;}}if(j1 != -1){int j2 = -1;for(int i = j1 + 1; i <= n; i ++){if(s[i] == '0'){j2 = i;break;}}if(j2 != -1){ans --;int j3 = -1;for(int i = j2 + 1; i <= n; i ++){if(s[i] == '1'){j3 = i;break;}}if(j3 != -1){ans --;}}}cout << ans << '\n';}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

C.Median Splits

在这里插入图片描述

思路

  • 可以数列中把小于等于k的数统统记为-1,因为彼此没有区别,无论是k - 1,k - 2,还是k - 100,在计算中位数时效果相同。同理,大于k的记作1。这样操作以后,整个新数列的和如果小于等于 0, 则原数列中位数小于等于k。(这是中位数常用技巧)

  • 题目给出的中位数式子是嵌套的,要满足外层中位数<=k,需要内层至少有2个中位数 <= k。

  • 将数列的三段简称为,前段,中段,后段,分类讨论三种情况,前+后,前+中,中+后。

  • 前+后,贪心,找到满足的中位数<=k的最短前缀和最短后缀,二者不重叠(至少相隔一个)则符合

  • 前+中,先找到最短前缀,在由有最短前缀后一位出发找第二段满足条件的,找得到即有解。注意,如果a1 <= k且 a2 >= k,前缀需要包括下a2,即取第一段为[a1,a2]

  • 中+后 同 前+中,改成后缀即可

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n,k;cin >> n >> k;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];vector<int> b(n+1);for(int i = 1; i <= n; i ++){if(a[i] <= k) b[i] = -1;else b[i] = 1;}int l = -1,r = -1,sum = 0;for(int i = 1; i <= n; i ++){sum += b[i];if(sum <= 0){l = i;break;}}sum = 0;for(int i = n; i >= 1; i --){sum += b[i];if(sum <= 0){r = i;break;}}if(l != -1 && r != -1 && l + 1 < r){cout << "YES\n";return;}if(l != -1){sum = 0;if(l == 1 && n >= 2 && b[l] == -1 && b[l+1] == 1) l ++;for(int i = l + 1; i <= n - 1; i ++){sum += b[i];if(sum <= 0){cout << "YES\n";return;}}}if(r != -1){sum = 0;if(r == n && n >= 2 && b[r] == -1 && b[r-1] == 1) r --;for(int i = r - 1; i >= 2; i --){sum += b[i];if(sum <= 0){cout << "YES\n";return;}}}cout << "NO\n";
}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

D.Local Construction

在这里插入图片描述

思路

  • 最后一个留下的数已知,正难则反,从倒数第一次删除往前考虑
  • 定义非大位置,为不满足 ai > ai-1 和 ai > ai+1的下标i,即是被删除的位置,非小位置则相反。
  • 不考虑第一个位置和最后一个位置,如果第 i 次删除的是非大位置,往 pj = i 的地方填入小值或许满足条件,发现填入,比已经敲定的值都小的值,且新填入的值按顺序递减可以满足题意。例如下图,空心点表示已经敲定的值,删除的就是,黑色实心点。
  • 为了避免第一个位置和最后一个位置出现问题,可以把前半部分的递减改为递增,同样符合
    在这里插入图片描述

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
typedef pair<int,int> PII;
void solve()
{int n;cin >> n;int mx = -1;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];vector<vector<int>> v(40);int init = -1;for(int i = 1; i <= n; i ++){mx = max(a[i],mx);if(a[i] == -1) init = i;else v[a[i]].push_back(i);}vector<int> ans(n+1),st(n+1);st[init] = 1;int up = 0,down = 0;for(int j = mx; j >= 1; j --){vector<int> tmp;if(j % 2 == 1){for(auto i : v[j]){if(i > init) ans[i] = ++up;else tmp.push_back(i);}reverse(tmp.begin(),tmp.end());for(auto i : tmp){ans[i] = ++up;}}else{for(auto i : v[j]){if(i > init)ans[i] = --down;else tmp.push_back(i);}reverse(tmp.begin(),tmp.end());for(int i : tmp){ans[i] = --down;}}}int mi = 1e9;for(int i = 1; i <= n; i ++){mi = min(ans[i],mi);}for(int i = 1; i <= n; i ++){ans[i] += -mi + 1;cout << ans[i] << " \n"[i == n];}}signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();
}

E. Keep the Sum

在这里插入图片描述

注:思维构造题,难度大,赛时仅4人通过

思路

  • 题目要求满足 ai + aj == k才可以操作,该条件苛刻。如果一对满足的i,j都没有,直接判断原序列是否非减即可
  • 反之,则找到了一对 i, j 满足条件。
  • 由于条件苛刻,考虑能否使得操作之后,仍然有数对满足条件,从而进一步操作。
  • 如果 ai + aj == k,那么可以交换 i / j和任意元素, 假定交换x位置的元素,那么先令ai -= ai - ax,aj += ai - ax,具体操作命令为 “i j a[i]-a[x]“,此时ax + aj == k ,再令 ax -= ax - 原ai ,aj += ax - 原ai ,则完成了i与x的交换,具体操作命令为 “x j 原a[i]-a[x]”
  • 那么,首先将 找到的满足条件的 i j 分别换到第一个和最后一个位置。然后将 ai 操作至0,aj操作至k,那么,所有为 0 的数都可以换到数组最前面,为 k的数都可以换到数组最后面,形成排好序的前缀,后缀。
  • 下一步,再将前缀的最后一个位置调整至 1,后缀的第一个位置调整为 k - 1,可以处理 1 和 k - 1。 重复直至 k/2和k/2 + 1。
  • 由于k较大,可以忽略数列了没有的数。

AC代码

#include<bits/stdc++.h>
#define int long longusing namespace std;
const int mod = 998244353;
typedef pair<int,int> PII;
void solve()
{int n,k;cin >> n >> k;vector<int> a(n+1);for(int i = 1; i <= n; i ++) cin >> a[i];map<int,int> mp;int x1 = -1,y1 = -1;for(int i = 1; i <= n; i ++){if(mp.find(k - a[i]) != mp.end()){x1 = mp[k-a[i]],y1 = i;break;}mp[a[i]] = i;}if(x1 == -1 && y1 == -1){for(int i = 1; i <= n - 1; i ++){if(a[i] > a[i+1]) {cout << -1 << '\n';return;}}cout << 0 << '\n';return;}vector<tuple<int,int,int>> ans;auto swap = [&](int l,int r,int x) -> void{if(l == r){return;}int tmp = a[r];ans.push_back({r,x,a[r] - a[l]});a[x] += a[r] - a[l];a[r] -= a[r] - a[l];ans.push_back({l,x,a[l]-tmp});a[x] += a[l] - tmp;a[l] -= a[l] - tmp;};swap(1,x1,y1);swap(n,y1,1);set<PII> s;for(int i = 2; i <= n - 1; i ++){s.insert({a[i],i});}int j1 = 1,j2 = n;while(s.size()){auto [l,id1] = *s.begin();auto [r,id2] = *s.rbegin();if(l - 0 < k - r){ans.push_back({j1,j2,a[j1] - l});a[j2] += a[j1] - l;a[j1] -= a[j1] - l;}else{ans.push_back({j2,j1,a[j2] - r});a[j1] += a[j2] - r;a[j2] -= a[j2] - r;}while(s.size() && (*s.begin()).first == a[j1]){auto tmp = *s.begin();j1 ++;s.erase({a[j1],j1});s.insert({a[j1],tmp.second});s.erase(s.begin());swap(j1,tmp.second,j2);}while(s.size() && (*s.rbegin()).first == a[j2]){auto tmp = *s.rbegin();j2 --;s.erase({a[j2],j2});s.insert({a[j2],tmp.second});s.erase(--s.end());swap(j2,tmp.second,j1);}}cout << ans.size() << '\n';for(auto &[x,y,z] : ans){cout << x << ' ' << y << ' ' << z << '\n';}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);int t = 1;cin >> t;while(t --) solve();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com