这次周赛题目其实挺不错的,很符合周赛惯用的出题风格,第一题睿智到随便谁都能写,后面两题一个是薄纱那些不会算时间复杂度的人,还有一个薄纱所有学的不怎么样的人的。。。
:。。。我记得我语言期末考试有题就是这个,。当时好像还有人不会来着。
:我做的时候情绪不是特别好,导致我其实第一眼就发现这个题是考的前缀和枚举的值进而在两边遍历相应的和,但是当时可能是肚子疼然后火气很大,我算错了时间复杂度,这个复杂度其实是,但是我想成了,我当时就寻思这怎么过啊,遂放弃,并且开始发骂。后来结束后一眼发现我估错了时间复杂度,我草了。。。因为分界是,故和是绝对独立的,所以只要枚举两次循环而不是两重循环。。。然后就是前缀和把给的那个等式拆分一下,有些细节还是要注意的。比如的时候数组下标可能变成负数。其他就是按照题意模拟就行了。
:这题不看视频我是真不会写。只能说我对图论的理解还是太片面了,然后也是,,,这题用了很巧妙的反证法和猜。我们不妨考虑第一个问题,也就是最大情况,第一个问题我们对所有的无向边都是可以随便走的,那么我们可以直接从起点开始,走到有向边我们就直接走,走到无向边,我们看是通过 到的这个点,然后给其赋以正负号。然后我们考虑最小的情况,最小的情况也就是所有的无向边我们都逆着走(你可以想一下怎么逆着走),就是考虑所有有向边能到达的点为一个集合,有向边到不了的点为另一个集合,那么这两个集合之间的路径只可能是两种情况,第一种情况,就是连着反向有向边,第二种情况就是逆向无向边。我们只需要认为规定一下正负就行了,这一点是最难想的。代码实现也有一定难度。
:
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,c;
cin>>a>>b>>c;
int maxn=max(a,b);
maxn=max(maxn,c);
int minn=min(a,b);
minn=min(minn,c);
cout<<maxn<<" "<<minn;
}
:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
map<int,int> mp;
const int N=5010;
int n;
ll s[N],a[N];
void solve(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
s[0]=a[0];
for(int i=1;i<n;i++){
s[i]=s[i-1]+a[i];
}
// for(int i=0;i<n;i++){
// cout<<s[i]<<" ";
// }
//cout<<endl;
ll res=-1e18;
int x0,y0,z0;
for(int y=0;y<=n;y++){
ll ans1=-1e18,ans2=-1e18;
int xx,yy,zz;
for(int x=0;x<=y;x++){
ll ansx=0;
if(x==0) ansx+=0;
else ansx+=2ll*s[x-1];
if(y==0) ansx-=0;
else ansx-=s[y-1];
if(ans1<ansx){
ans1=ansx;
xx=x;
}
}
for(int z=y;z<=n;z++){
ll ansy=0;
if(y!=0) ansy-=s[y-1];
if(z!=0) ansy+=2ll*s[z-1];
ansy-=s[n-1];
if(ans2<ansy){
ans2=ansy;
zz=z;
}
}
yy=y;
if(res<ans1+ans2){
x0=xx,y0=yy,z0=zz;
res=ans1+ans2;
}
//cout<<res<<endl;
}
cout<<x0<<" "<<y0<<" "<<z0<<"\n";
}
int main(){
//IOS;
solve();
return 0;
}
:
#include <bits/stdc++.h>
#define ll long long
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
using namespace std;
const int N=300010,M=2*N;
int e[M],ne[M],w[M],idx=0,h[M],n,m,ans[N],s;
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
bool st[N];
int dfs(int u,int type){
int res=1;
st[u]=true;
for(int i=h[u];~i;i=ne[i]){
int j=e[i];
if(st[j]) continue;
if(type==0){
res+=dfs(j,0);
if(w[i]) ans[abs(w[i])]=w[i];
}
else{
if(!w[i]) res+=dfs(j,1);
else ans[abs(w[i])]=-w[i];
}
}
return res;
}
int main(){
IOS;
memset(h,-1,sizeof h);
memset(ans,0,sizeof ans);
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
int t,a,b;
cin>>t>>a>>b;
if(t==1){
add(a,b,0);
}
else{
ans[i]=i;
add(a,b,i);
add(b,a,-i);
}
}
memset(st,0,sizeof st);
cout<<dfs(s,0)<<"\n";
for(int i=1;i<=m;i++){
// cout<<ans[i]<<" ";
if(ans[i]<0) cout<<"-";
else if(ans[i]>0) cout<<"+";
}
cout<<"\n";
memset(st,0,sizeof st);
cout<<dfs(s,1)<<"\n";
for(int i=1;i<=m;i++){
//cout<<ans[i]<<" ";
if(ans[i]<0) cout<<"-";
else if(ans[i]>0) cout<<"+";
}
return 0;
}
下次注意了,别发癫(当题做不出来时候),多找找自己脑子的原因,其实也没有想象中的那么菜。。。