传送门:AtCoder Regular Contest 165 - AtCoder
本次习题参考了樱雪猫大佬的题解,大佬的题解传送门如下:Atcoder Regular Contest 165 - 樱雪喵 - 博客园 (cnblogs.com)
A - Sum equals LCM
第一题不算特别难
B - Sliding Window Sort 2
对于这道题而言,我们不难看出,如果想让该字符串尽可能的大,那最好的方式就是不改变,如果改变了,尽可能的向右边改变,同时尽可能的少改变。我们不如从前向后进行枚举,从而筛选出是第一个交换尽可能向右的下标,并记录。代码如下:
#include
using namespace std;
// #define int long long
typedef long long ll;
typedef pair PII;
const int N=998244353;
int n,k;
int b[5000005];
void icealsoheat(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>b[i];
}
setq;
for(int i=1;i<=k;i++)q.insert(b[i]);
vectorc(n+5,0);
int id=0;
int mx=0;
for(int i=1;i<=n-k+1;i++){
if(i-1)q.erase(b[i-1]),q.insert(b[i+k-1]);
if(c[i])continue;
int l=0;
auto it=q.begin();
for(int j=i;jmx){
mx=l;
id=i;
}
}
if(id)sort(b+id,b+id+k);
for(int i=1;i<=n;i++)cout<>_;
while(_--){
icealsoheat();
}
}
C - Social Distance on Graph
首先,没有重边,没有环,简单的无向图。最开始我想到了最小生成树,但是没搞出来,后来看佬的码,惊讶的发现确实是最小生成树,只是我想的还是太浅了,不够深入。
既然我们想让最小值最大,那么我们尽可能的让最小的边通过涂色和其他边和在一起。如果是不同的颜色的两个点,则这条边不存在,无法相连。所以我们可以用最小生成树来将最小的顶点优先考虑。并且将其进行染色,将这两个点儿染成不同的颜色。同时并继续向后慢慢更新,这里可以通过并查集来进行实现。在最后,我们比较出最小值即可。
代码如下:
#include
using namespace std;
#define int long long
typedef long long ll;
typedef pair PII;
const int N=998244353;
const int MX=0x3f3f3f3f3f3f3f3f;
int n,k,m;
int c[5000005];
int pre[1000005];
struct we{
int l,r,w;
bool operator <(const we &k)const{
return w>n>>m;
for(int i=1;i<=n;i++){
pre[i]=i;
c[i]=-1;
}
vector>ve(n+5);
for(int i=1;i<=m;i++){
int l,r,w;
cin>>l>>r>>w;
hh[i].l=l;
hh[i].r=r;
hh[i].w=w;
}
sort(hh+1,hh+1+m);
for(int i=1;i<=m;i++){
int xx=find(hh[i].l);
int yy=find(hh[i].r);
if(xx==yy){
continue;
}
pre[xx]=yy;
ve[hh[i].l].push_back({hh[i].r,hh[i].w});
ve[hh[i].r].push_back({hh[i].l,hh[i].w});
}
auto dfs=[&](auto self,int x,int fa)->void{
for(auto [i,j]:ve[x]){
if(i==fa||c[i]!=-1)continue;
c[i]=c[x]^1;
self(self,i,x);
}
};
for(int i=1;i<=n;i++){
if(pre[i]==i){
c[i]=0;
dfs(dfs,i,-1);
break;
}
}
int ans=MX;
for(int i=1;i<=m;i++){
if(c[hh[i].l]==c[hh[i].r]){
ans=min(ans,hh[i].w);
}
}
for(int i=1;i<=n;i++){
sort(ve[i].begin(),ve[i].end(),cmp);
}
for(int i=1;i<=n;i++){
if(ve[i].size()>1){
ans=min(ans,ve[i][0].second+ve[i][1].second);
}
}
cout<>_;
while(_--){
icealsoheat();
}
}
D - Substring Comparison
本题对于算法的考察比较多,我认为是一道比较好的题。这题我没有一点思路,是直接看佬的代码和思路的,让我恍然大悟。既然n是2000,那就支持双重循环了。首先,如果a=c并且d>=b的话,那一定是输出no的,我们可以优先排前面的,最开始让a#include