2025 --【J+S 二十连测】-- 第十一套 总结
总结
T1
考场上很快写出了正解,但是由于题目理解错误,失分
T2
考场上很快写出了正解,没有问题,但是代码被吃了。。。
T3
考场上很快写出了正解,没有问题
T4
考场上很快写出了正解,但是假了,失分
T5
考场上很快写出了正解,但是假了,失分
题解
T1
照题意模拟即可,但是要倒着做
代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=2e5+5;
signed main()
{
freopen("sky.in","r",stdin);
freopen("sky.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;cin>>n;
string s,t;cin>>s>>t;
s=' '+s,t=' '+t;
for(int i=n;i>=3;i--) if(s[i-1]==s[i-2]&&s[i-2]=='0') s[i]='0';
cout<<(s==t?"YES":"NO");
return 0;
}
T2
先重新标号,然后对 \(b\) 数组看是不是通过反转若干无交的子段即可
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=2e5+5;
signed main()
{
freopen("sky.in","r",stdin);
freopen("sky.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;cin>>n;
string s,t;cin>>s>>t;
s=' '+s,t=' '+t;
for(int i=n;i>=3;i--) if(s[i-1]==s[i-2]&&s[i-2]=='0') s[i]='0';
cout<<(s==t?"YES":"NO");
return 0;
}
T3
用线段树模拟即可
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=2e6+5;
int a[maxn];
struct SGT
{
int win[maxn<<2],jin[maxn<<2],n;
void init(int len)
{
n=len;
}
void update(int x,int l,int r,int lt,int rt,int p)
{
if(l>rt||r<lt) return;
if(l>=lt&&r<=rt&&l==r) win[x]+=p;
if(l>=lt&&r<=rt) return;
int mid=(l+r)>>1;
update(x*2,l,mid,lt,rt,p);
update(x*2+1,mid+1,r,lt,rt,p);
int a=win[x*2],b=win[x*2+1];
jin[x]=jin[x*2]+jin[x*2+1];
if(a>=b||l>1) win[x]=abs(a-b);
else win[x]=0,jin[x]+=b-a;
}
}tree;
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
ch=getchar();
if(ch=='-') f=-1;
}
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
signed main()
{
freopen("rain.in","r",stdin);
freopen("rain.out","w",stdout);
int n=(1<<(read())),m=read();
for(int i=1;i<=n;i++) a[i]=read();
tree.init(n);
for(int i=1;i<=n;i++) tree.update(1,1,n,i,i,a[i]);
while(m--)
{
int l=read(),r=read(),x=read();
tree.update(1,1,n,l,r,x);
cout<<tree.jin[1]<<endl;
}
return 0;
}
T4
我们先来把这道题弱化一下。把它弱化成只有高级廊桥。即加工零件这道题目。
由于这道题目里面有低级廊桥,所以我们考虑当前我到这一个点有三种情况。
- 我走了奇数个时间。
- 我走了偶数的时间,但是我走了高级廊桥。
- 我走了偶数个时间,但我没走高级廊桥。
对于前两种情况我们会发现他一定走了高级廊桥。那么我在高级廊桥上面来回移动。就可以增加二的时间。所以对于前两种情况,就是我到了那个点的最短时间,然后一直加2直到r。
而对于第三种情况的话。就只能在低级廊桥上面来回移动,那么就只能加4了。
但是第2种和第3种可能会有重复。当我们发现第3种情况到的时间比第2种早的时候,此时在第2种中和最短路径模式同余的那些情况,一定都是重复的。
反过来的话,我们就看,如果说第3种和第2种的最短路模4同余。那么第3种的每一种情况都是多余的。反之,我们将第2种情况的起点加二。因为两者均是偶数,余数差一定是二。然后接下来所有第3种情况一定都是多余的。
最后输出答案即可。
代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=2e5+5;
int dis1[maxn][2][2],vis[maxn][2][2];
int odd[maxn],evn0[maxn],evn1[maxn];
vector<pair<int,int> > g[maxn];
struct node
{
int z,a,b,c;
bool operator <(const node &a) const
{
return z>a.z;
}
};
void bfs1()
{
memset(dis1,0x3f,sizeof(dis1));
dis1[1][0][0]=0;
priority_queue<node> q;
q.push({0,1,0,0});
while(!q.empty())
{
int a=q.top().a,b=q.top().b,c=q.top().c;
q.pop();
if(vis[a][b][c]) continue;
vis[a][b][c]=1;
for(auto nxt:g[a])
{
int to=nxt.first,w=nxt.second,y=(b+w)%2,z=c|(w==1);
if(dis1[to][y][z]>dis1[a][b][c]+w)
{
dis1[to][y][z]=dis1[a][b][c]+w;
q.push({dis1[to][y][z],to,y,z});
}
}
}
}
int f(int s,int p,int l,int r)
{
if(s>r) return 0;
int minn=(max(0ll,l-s)+p-1)/p,maxx=(r-s)/p;
return max(0ll,maxx-minn+1);
}
signed main()
{
freopen("friendship.in","r",stdin);
freopen("friendship.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,w;cin>>u>>v>>w;
w++;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
bfs1();
memset(odd,0x3f,sizeof(odd));
memset(evn0,0x3f,sizeof(evn0));
memset(evn1,0x3f,sizeof(evn1));
for(int i=1;i<=n;i++)
{
odd[i]=min(dis1[i][1][0],dis1[i][1][1]);
evn1[i]=dis1[i][0][0];
evn0[i]=dis1[i][0][1];
}
int q;cin>>q;
while(q--)
{
int x,l,r,ans=0;cin>>x>>l>>r;
if(odd[x]<inf) ans+=f(odd[x],2,l,r);
if(evn1[x]<inf) ans+=f(evn1[x],4,l,r);
if(evn0[x]<inf) ans+=f(evn0[x],2,l,r);
if(evn0[x]<inf&&evn1[x]<inf)
{
if(evn0[x]<=evn1[x]) ans-=f(evn1[x],4,l,r);
else
{
if(evn0[x]%4==evn1[x]%4) ans-=f(evn0[x],4,l,r);
else ans-=f(evn0[x]+2,4,l,r);
}
}
cout<<ans<<endl;
}
return 0;
}
T5
不难发现,如果说我每一次都取当前这个数的\(lowbit\)。那么先手必赢。所以我们只需要看\(n\) 的 \(low bit\)是否大于 \(k\) 即可。
代码
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f3f3f3f3f
#define int long long
#define endl '\n'
using namespace std;
const int maxn=2e5+5;
signed main()
{
freopen("done.in","r",stdin);
freopen("done.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t;cin>>t;
while(t--)
{
int n,k;cin>>n>>k;
if((n&-n)<=k) cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
}
return 0;
}
本文来自博客园,作者:Engle_Chen,欢迎转载,转载请注明原文链接:https://www.cnblogs.com/EagleChenzhilong/p/19124378
,感谢阅读!
浙公网安备 33010602011771号