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