Nov 7
滑铁卢式的惨败。
T1 P10205 [JOI 2024 Final] 室温 / Room Temperature
场上并没能正确做出来。
当时同样是 %t 处理了每个 a,然后就想着取一下左右端点,答案是中间就行了。
这个想法大抵上是正确的,但也只是大抵上正确。
我们可能会有情况如下。
如果将最左边的去一件衣服(+t),让他成为新的右端点,下一个点成为新的左端点,无法保证这个情况比之前说的做法劣。
所以我们也要考虑上就是了。
排个序,枚举左右相邻点为左右端点算就行。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MN=1e6+116;
int a[MN], n, t, ans;
void Read(){
cin>>n>>t;
for(int i=1; i<=n; ++i) cin>>a[i];
for(int i=1; i<=n; ++i) a[i]%=t;
return;
}
void Solve(){
Read(); sort(a+1,a+n+1);
ans=(a[n]-a[1]+1)/2;
for(int i=1; i<=n; ++i){
ans=min(ans,(a[i]+t-a[i+1]+1)/2);
}
cout<<ans<<'\n';
return;
}
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
Solve();
return 0;
}
T2 【MX-X7-T3】[LSOT-3] 寄存器
我并没有做出来,因为我并没有找出来正确的删除逻辑。
一个我的错误想法,这个问题就是以任意黑色节点为根跑出来一个尽可能小的,包含所有黑色的联通快,之后再将里边白色的联通块删除。
这个明显在小数据或者树成链问题是不大的,但是考虑以下的情况。
树分三层,根是黑色,三个儿子是白色,每个儿子都有一个儿子,儿子的儿子是黑色。
这种情况我们按照之前的思路是需要四次的,然而存在一个三次的操作方法。
我们先电整张图,之后断掉儿子与儿子的儿子间的边,再电一次剩下的图,最后电一下根节点。
于是想分层一样的,我们就成功得出了一种优于之前思路的,按照分层进行的手段。
那么显然的,我们只需要找出来这棵树最多能被分层多少图就行了。
我们把不同的颜色之间连的边的边权设为 1, 把相同颜色之间连的边边权设为 0, 之后正常跑树的直径,这个样子直径的每一个单位长度就代表着一次分层。
我们从这个直径的重点开始就行了,答案是 (len+1)/2.
代码↓
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MN=3e6+316;
struct Node{
int nxt, to;
}node[MN];
int head[MN], tottt;
void insert(int u, int v){
node[++tottt].to=v;
node[tottt].nxt=head[u];
head[u]=tottt; return;
}
int n, a[MN], cnt1=0;
void Read(){
cin>>n;
for(int i=1; i<=n; ++i){
cin>>a[i];
cnt1+=a[i];
}
for(int i=1; i<n; ++i){
int u, v;
cin>>u>>v;
insert(u,v);
insert(v,u);
}
}
int stt, maxn=0;
void dfs(int u, int father, int depth){
if(a[u]!=a[father]) depth++;
if(a[u]==1&&depth>maxn){
maxn=depth; stt=u;
}
for(int i=head[u];i;i=node[i].nxt){
int v=node[i].to;
if(v==father) continue;
dfs(v,u,depth);
}
}
void Solve(){
Read();
if(cnt1==0){
cout<<0<<'\n';
return;
}
dfs(1,0,0); maxn=0;
dfs(stt,0,0);
//cout<<maxn<<'\n';
cout<<(maxn+1)/2<<'\n';
return;
}
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
Solve();
return 0;
}
T3 P12649 [KOI 2024 Round 2] 收集彩球
一道神秘图论建模题。
把每个颜色看成是点,上边连下边。
统计联通快四种情况:成链,成环,自环,其他。
其他即两个以上出度为 0,这个就是无解。
代码↓
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MN=1e6+116;
struct Node{
int nxt, to;
}node[MN];
int head[MN], tottt=1;
void insert(int u, int v){
node[++tottt].to=v;
node[tottt].nxt=head[u];
head[u]=tottt; return;
}
int n, a[MN], b[MN];
int ans=0, vis[MN], deg[MN];
int dfs(int u){
int res=0;
if(deg[u]==0) res++;
vis[u]=true;
for(int i=head[u];i;i=node[i].nxt){
int v=node[i].to;
if(vis[v]) continue;
res+=dfs(v);
}
return res;
}
void Read(){
cin>>n;
for(int i=1; i<=n; ++i) cin>>a[i]>>b[i];
return;
}
void Solve(){
Read(); ans=n;
for(int i=1; i<=n; ++i){
insert(a[i],b[i]);
insert(b[i],a[i]);
deg[a[i]]++;
if(a[i]==b[i]){
vis[a[i]]=true;
ans--;
}
}
for(int i=1; i<=n; ++i){
if(vis[i]) continue;
int res=dfs(i);
if(res>=2){
cout<<-1<<'\n'; return;
}
ans++;
}
cout<<ans<<'\n';
return;
}
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
Solve();
return 0;
}

浙公网安备 33010602011771号