A. Number of Apartments

题意:用3、5、7凑数,若能凑出给出方案,不能则输出-1。

思路:观察发现除了1 2 4凑不到以外其他都凑得到。那么关于方案的话,既然其他数都凑得到,我们就可以用dp的思想每次试探着来,若减去当前数还是个可以凑得到的就继续减直到等于0。

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} }; ll all[3] = {7,5,3};
ll Map[2000];
ll cnt[10]; int main()
{
int kase;
cin>>kase;
Map[1] = 1, Map[2] = 1, Map[4] = 1;
while(kase--)
{
ll n = read();
mem(cnt,0);
if(Map[n])
{
cout<<-1<<endl;
continue;
}
while(n)
{
rep(i,0,2) if(n-all[i]>=0&&!Map[n-all[i]])
{
cnt[all[i]]++;
n -= all[i];
break;
}
}
cout<<cnt[3]<<' '<<cnt[5]<<' '<<cnt[7]<<endl;
}
return 0;
}

B. Barrels

题意:有n个无限容量的水桶,现在各含a[i]的水,现在可以随便k次,问最大最小值差的最大值。

思路:水题,从次大的水桶开始倒k桶,全部倒进最大的那一桶。

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} }; ll a[maxn]; int main()
{
int kase;
cin>>kase;
while(kase--)
{
ll n = read(), k = read();
rep(i,1,n) a[i] = read();
sort(a+1,a+1+n);
int p = 1;
ll cnt = 1;
for(int i=n-1; i>=1&&cnt<=k; i--)
{
a[n] += a[i];
cnt++;
}
cout<<a[n]<<endl;
}
return 0;
}

C. Numbers on Whiteboard

题意:每次可以把任意两个数a,b替换成\(\lceil {(a+b)/2} \rceil\),可以操作n-1次,问最后剩下的一个数能达到的最小值是多少。并且输出每一步操作。

思路:从后面大的开始,先把a[n] a[n-2]变成a[n-1],再把两个a[n-1]结合变成1个a[n-1],然后就可以一路从a[n-3]往前平推,每次都会使得值-1。

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} }; typedef struct Ans
{
ll a;
ll b;
}A;
A ans[maxn]; int main()
{
int kase;
cin>>kase;
while(kase--)
{
ll n = read();
ll k = n-1;
if(n==2)
{
cout<<2<<endl;
cout<<1<<' '<<2<<endl;
continue;
}
ans[1].a = n;
ans[1].b = n-2;
ans[2].a = n-1;
ans[2].b = n-1;
int p = 2;
ll cur = n-1;
per(i,n-3,1)
{
ans[++p].a = cur;
ans[p].b = i;
cur = (cur+i+1)/2;
}
cout<<cur<<endl;
rep(i,1,p) cout<<ans[i].a<<' '<<ans[i].b<<endl;
}
return 0;
}

D. String Deletion

题意:给你一个01串,每一次操作必须先删掉任意一个位置,然后删除掉最长相同前缀。问最多能维持多少次这个操作。

思路:既然每次操作是对一个相同前缀下手,那我们就把每一块相同数所组成的联通块看成一个整体。同时记录他们的长度。

如1110010就可以看成

111 00 1 0

写成联通块(长度表示)

3 2 1 1

然后我们发现,会使得我们操作变少的是联通块长度为1的,我们现在想让1尽量的维持下去,即不让他在每次操作前减完自身使得要牺牲下一个联通块。

首先考虑到如果一个数大于1,那么“删除”这一步减自己就好了,不浪费别的。

而如果一个数等于1, 那我们就要考虑从它后面(轮到它当前缀时)找一些大于2的数(找2的话一减又多出个1来),这样就可以让它维持下去,删除前缀时就可以减掉当前的1而不影响后面一个。而找不到的话,那就只能减去当前这个1,然后再牺牲下一个联通块了(下一个联通块变成新的前缀)。

主要的思想就是上面说的,现在考虑怎么实现“在后面找一个大于2的数”,如果每个位置都往后找,那就是\(O(n^2)\)的时间复杂度,肯定不行。

我们发现当前i位置往后,若找到某个位置j来删除,那么在i+1位置,肯定也是从j开始往后找的,也就是前j-1个位置既然都不满足i位置,那么肯定也不满足i+1位置。这样我们只需要用双指针走一遍这个数组即可。时间复杂度\(O(2n)\)

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} }; string s;
ll block[maxn];
int p = 0;
ll solve()
{
int q = 1;
ll ans = 0;
bool flag = 0;
rep(i,1,p)
{
if(flag)
{
ans++;
i += 1;
continue;
}
if(block[i]>1) ans++;
else
{
while(q<i||(q<=p&&block[q] <= 1)) q++;
if(q>p)
{
flag = 1;
ans++;
i += 1;
}
else
{
block[q]--;
ans++;
}
}
}
return ans;
} int main()
{
int kase;
cin>>kase;
while(kase--)
{
p = 0;
ll n = read();
string s;
cin>>s;
block[++p] = 1;
rep(i,1,n-1)
{
if(s[i]==s[i-1]) block[p]++;
else block[++p] = 1;
}
cout<<solve()<<endl;
}
return 0;
}

E. String Reversal

题意: 给一个字符串,每次可以相邻位置交换,问最少多少次可以使得字符串变成原来的颠倒字符串。

思路:显然有比直接一步步交换过去更优的策略。

比如acbac,我们想让第一个a变到最后一个位置去,完全不需要第一个位置的a动,只需要最靠近右边的a和c交换即可,一步到位。

所以策略就是每次都让最靠近右边的,和当前字符相同的字符移动就好。

但是这样会有个问题,就是有些位置被移动过,它左边的数再经过它往右交换时,距离就要减去这个空位。那怎么维护这个东西呢?

我们把这个“空位”产生的影响描述出来就是,一开始找到第一个位置的最靠右的相同字符,位置为p1,丢到最后,距离是n-p1。

然后第二个位置最靠右相同字符的位置p2, 若p2<p1,即p1这个空位对p2产生影响了,那就是n-p2-1。同理若p3<p2, 那就是n-p3-2。

所以就只需要统计p位置后面有多少空位即可,然后减去这个数。

这个时候树状数组的作用就来了。

为了方便,我们反过来看,从最后开始往前丢数,一开始是p1-1, 然后若p2>p1, 就p2-1-1,其次是p3-2-1(后面的-1是到1的距离,再减的就是空位个数)。所以我们的空位对计数是负贡献,把一开始[1,n]的区间每个位置都置为1, 一旦产生一个位置p产生空位,就在p这个位置-1,这样前缀和即表示(p-空位个数),每次的贡献就是前缀和-1。

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} }; ll n;
string s;
queue<ll> q[50];
ll c[maxn]; inline int id(int p)
{
return s[p-1] - 'a' + 1;
} inline void add(int p, ll val)
{
for(int i=p; i<=n; i+=lowbit(i)) c[i] += val;
} inline ll ask(int p)
{
ll ans = 0;
for(int i=p; i>=1; i-=lowbit(i)) ans += c[i];
return ans;
} int main()
{
n = read();
cin>>s;
rep(i,1,n) q[id(i)].push(i), add(i,1);
ll ans = 0;
per(i,n,1)
{
int pos = q[id(i)].front();
q[id(i)].pop();
ans += ask(pos)-1; add(pos, -1);
}
cout<<ans<<endl;
return 0;
}

Educational Codeforces Round 96 ABCDE 题解(详解)的更多相关文章

  1. Educational Codeforces Round 64 部分题解

    Educational Codeforces Round 64 部分题解 不更了不更了 CF1156D 0-1-Tree 有一棵树,边权都是0或1.定义点对\(x,y(x\neq y)\)合法当且仅当 ...

  2. Educational Codeforces Round 64部分题解

    Educational Codeforces Round 64部分题解 A 题目大意:给定三角形(高等于低的等腰),正方形,圆,在满足其高,边长,半径最大(保证在上一个图形的内部)的前提下. 判断交点 ...

  3. Educational Codeforces Round 63部分题解

    Educational Codeforces Round 63 A 题目大意就不写了. 挺简单的,若果字符本来就单调不降,那么就不需要修改 否则找到第一次下降的位置和前面的换就好了. #include ...

  4. Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal 题解(思维+逆序对)

    题目链接 题目大意 给你一个长度为n的字符串,可以交换相邻两个元素,使得这个字符串翻转,求最少多少种次数改变 题目思路 如果要求数组排序所需要的冒泡次数,那其实就是逆序对 这个也差不多,但是如果是相同 ...

  5. Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal (思维,逆序对)

    题意:给你一个字符串,每次可以调换现字符串的相邻两个字符,问最少操作多少次使得这个字符串等于其反转过来的字符串. 题解:先考虑字符串中没有相同字符的情况,那么我们每次将目前字符串的最后一个字符一直调换 ...

  6. Educational Codeforces Round 96 (Rated for Div. 2) D. String Deletion (思维)

    题意:有一个\(01\)串,每次操作要先删除一个位置上的元素,然后删除相同前缀和,直到字符串被删完,问最多能操作多少次. 题解: 对于一个长度大于\(1\)的相同前缀,我们最多只能对它操作一次,然后就 ...

  7. Educational Codeforces Round 96 (Rated for Div. 2)

    A. Number of Apartments 题意:求方程的解 思路:直接模拟就行 代码: #include<iostream> #include<cstdio> #incl ...

  8. Educational Codeforces Round 16---部分题解

    710A. King Moves 给你图中一点求出它周围有几个可达的点: 除边界之外都是8个,边界处理一下即可: #include<iostream> #include<cstdio ...

  9. Educational Codeforces Round 38 部分题解

    D. Buy a Ticket 分析 建一个源点,连向所有结点,边的花费为那个结点的花费,图中原有的边花费翻倍,最后跑一遍最短路即可. code #include<bits/stdc++.h&g ...

  10. Educational Codeforces Round 110 A-D 题解

      A. Fair Playoff 题目大意:有4个人进行比赛,第一个和第二个比,第三个和第四个比,之后各自的胜者再比,最开始每个人持有一个数字,每场比赛持有数字较大的选手会胜出,问最开始持有数字最大 ...

随机推荐

  1. 一款让 Everything 更加如虎添翼的 .NET 开源辅助工具!

    前言 相信很多同学都应该用过 Everything 这个实用的 Windows 文件搜索神器吧,今天大姚给大家分享一款让 Everything 更加如虎添翼的 .NET 开源辅助工具:Everythi ...

  2. day12“函数”进阶学习让你更上一层楼

    函数进阶 多函数程序执⾏流程 拆包 递归 可变和不可变类型 多函数程序执⾏流程 共用全局变量 # 1. 定义全局变量 num = 0 def test1(): global num # 修改全局变量 ...

  3. nextflow 基础

    Nextflow 核心知识点与使用指南 一.安装与依赖 环境要求 • Java:Nextflow 需 Java 17+ 环境,可通过 apt-get 或 SDKMAN 安装. • 操作系统:支持 Li ...

  4. MongoDB学习(二)

    MongoDB基本操作 查看数据库 语法: show databases 选择数据库 语法:use 数据库名 注意:在MongoDB中选择不存在的数据库不会报错,后期当该数据库有数据时,系统会自动创建 ...

  5. python基础必练题!!

    水仙花数 水仙花数 info = 3 while info: # 用户输入数字 try: print(f"请输入数字,您有{info}次机会!!") num = int(input ...

  6. Windows-exporter(node-exporter)+ Prometheus + Grafana资源监控搭建

    在性能测试过程中,资源监控可以时刻掌握被测软件运行环境的各类数据,从而更加直观地反馈测试过程中潜在的问题,下面是基于Windows-exporter(node-exporter)+ Prometheu ...

  7. 阿里云Ansible自动化运维平台部署

    以下是在阿里云平台上基于Ansible实现自动化运维的完整实践指南,整合所有核心操作流程和命令,适配指定的服务器规划: 一.环境规划 主机名 IP地址 角色 操作系统 manage01 192.168 ...

  8. 关于C#的Dynamic调用方法前的一些准备的小Demo

    using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Linq; us ...

  9. golang unsafe遇上字符串拼接优化导致的bug

    最近料理老项目的时候被unsafe坑惨了,这里挑一个最不易察觉的错误记录一下. 这个问题几乎影响近几年来所有的go版本,为了方便讨论我就用最新版的1.24.3做例子了. 线上BUG 我们有一个收集集群 ...

  10. RAG越来越不准?从Dify和ima知识库看元数据与标签如何让大模型更懂你

    你是否有这样的经历:"知识库文档越来越多,知识库问答却越来越不靠谱,RAG检索到的都是一堆不相关的内容." 在这个信息爆炸的时代,我们不缺资料,缺的是找到"对的资料&qu ...