https://ac.nowcoder.com/acm/contest/6874#question
巨木之森【树的直径】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*4+10;
LL h[N],e[N],ne[N],w[N],idx;
LL n,m,dist[N],dist1[N],dist2[N],sum;
int ans;
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int fa,LL d)
{
dist[u]=d;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dfs(j,u,d+w[i]);
}
}
void dfs1(int u,int fa,LL d,LL dist[N])
{
dist[u]=d;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
dfs1(j,u,d+w[i],dist);
}
}
int main(void)
{
memset(h,-1,sizeof h);
cin>>n>>m;
for(int i=1;i<=n-1;i++)
{
int a,b,c; cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
sum+=c;
}
dfs(1,-1,0);
LL root1=1,len1=0;
for(int i=1;i<=n;i++) if(len1<dist[i]) len1=dist[i],root1=i;
dfs(root1,-1,0);
LL root2=1,len2=0;
for(int i=1;i<=n;i++) if(len2<dist[i]) len2=dist[i],root2=i;
dfs1(root1,-1,0,dist1);
dfs1(root2,-1,0,dist2);
vector<LL>ve;
for(int i=1;i<=n;i++)
{
LL temp=sum*2-max(dist1[i],dist2[i]);
ve.push_back(temp);
}
sort(ve.begin(),ve.end());
int cnt=0;
for(int i=0;i<ve.size();i++)
if(ve[i]<=m) cnt++,m-=ve[i];
cout<<cnt<<endl;
return 0;
}
乐团派对【贪心 / DP】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
int a[N],n,maxv=0;
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],maxv=max(maxv,a[i]);
if(maxv>n) puts("-1");
else
{
sort(a+1,a+n+1);
int cnt=0,ans=0;
vector<int>ve;
maxv=0;
for(int i=1;i<=n;i++)
{
maxv=max(maxv,a[i]);
cnt++;
if(cnt==maxv) ve.push_back(cnt),ans++,cnt=0,maxv=0;
}
if(cnt<maxv)
{
for(int i=ve.size()-1;i>=0;i--)
{
cnt+=ve[i],ans--;
if(cnt>=maxv) break;
}
ans++;
}
cout<<ans;
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*4+10;
int n,a[N],dp,maxv[N];
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(i>=a[i]) dp=max(maxv[i-a[i]]+1,dp);
else dp=0;
maxv[i]=max(maxv[i-1],dp);
}
if(dp==0) puts("-1");
else cout<<dp;
return 0;
}
光玉小镇【状压DP TSP】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=210;
LL f[1<<17][17],dist[25][25],n,m,t;
vector< pair<int,int> >ve;
int st[N][N];
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
char c[N][N];
void bfs(int x,int y)
{
st[x][y]=0;
queue<pair<int,int>>q; q.push({x,y});
while(q.size())
{
auto temp=q.front(); q.pop();
x=temp.first,y=temp.second;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i],tempy=y+dy[i];
if(tempx<=0||tempx>n||tempy<=0||tempy>m) continue;
if(st[tempx][tempy]!=-1) continue;
if(c[tempx][tempy]=='#') continue;
st[tempx][tempy]=st[x][y]+1;
q.push({tempx,tempy});
}
}
}
int main(void)
{
memset(dist,0x3f,sizeof dist);
cin>>n>>m>>t;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>c[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(c[i][j]=='S') ve.push_back({i,j});
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(c[i][j]=='T') ve.push_back({i,j});
bool flag=0;
for(int i=0;i<ve.size();i++)
{
memset(st,-1,sizeof st);
bfs(ve[i].first,ve[i].second);
for(int j=0;j<ve.size();j++)
{
int x=ve[j].first,y=ve[j].second;
if(st[x][y]==-1) flag=1;
dist[i][j]=st[x][y];
}
}
memset(f,0x3f,sizeof f);
f[1][0]=0;
LL cnt=ve.size();
for(int i=0;i<(1<<cnt);i++)
{
for(int j=0;j<cnt;j++)
{
if(i>>j&1)
{
for(int k=0;k<cnt;k++)
{
int temp=i-(1<<j);
if(temp>>k&1) f[i][j]=min(f[i][j],f[i-(1<<j)][k]+dist[k][j]);
}
}
}
}
LL ans=0x3f3f3f3f;
for(int i=1;i<cnt;i++) ans=min(ans,f[(1<<cnt)-1][i]+dist[i][0]);
if(flag) puts("-1");
else cout<<ans+t*(cnt-1);
return 0;
}
巅峰对决【线段树】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
struct node
{
int l,r,minv,maxv;
}tr[N*4];
int n,m,w[N];
void build(int u,int l,int r)
{
tr[u]={l,r};
if(l==r) return;
int mid=tr[u].l+tr[u].r>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
}
void pushup(int u)
{
tr[u].maxv=max(tr[u*2].maxv,tr[u*2+1].maxv);
tr[u].minv=min(tr[u*2].minv,tr[u*2+1].minv);
}
node query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
else
{
int mid=(tr[u].l+tr[u].r)/2;
int maxv=0,minv=1e9;
if(l<=mid)
{
node temp=query(u*2,l,r);
maxv=max(maxv,temp.maxv);
minv=min(minv,temp.minv);
}
if(r>=mid+1)
{
node temp=query(u*2+1,l,r);
maxv=max(maxv,temp.maxv);
minv=min(minv,temp.minv);
}
node temp={0,0,minv,maxv};
return temp;
}
}
void modify(int u,int x,int v)
{
if(tr[u].l==x&&tr[u].r==x)
{
tr[u].minv=v;
tr[u].maxv=v;
}
else
{
int mid=tr[u].l+tr[u].r>>1;
if(x<=mid) modify(u*2,x,v);
else modify(u*2+1,x,v);
pushup(u);
}
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
build(1,1,n);
for(int i=1;i<=n;i++) modify(1,i,w[i]);
while(m--)
{
int op,x,y; cin>>op>>x>>y;
if(op==1) modify(1,x,y);
else
{
node temp=query(1,x,y);
if((temp.maxv-temp.minv)==(y-x)) puts("YES");
else puts("NO");
}
}
return 0;
}
使徒袭来【二分】
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int n; cin>>n;
double l=1,r=n;
while(r-l>1e-6)
{
double mid=(l+r)/2;
if(mid*mid*mid>=n) r=mid;
else l=mid;
}
printf("%.3lf",l*3);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int n; cin>>n;
printf("%.3lf",3.0*pow(n,1.0/3));
return 0;
}
核弹剑仙【dfs / 拓扑】
暴力dfs
#include<bits/stdc++.h>
using namespace std;
const int N=1e3*2+10;
int h[N],e[N],ne[N],idx;
int d[N],st[N],cnt[N],n,m;
bitset<1005>f[N];
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int dfs(int u)
{
st[u]=1;
int sum=0;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(st[j]) continue;
sum+=dfs(j);
}
return sum+1;
}
int main(void)
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--)
{
int a,b; cin>>a>>b;
add(b,a);
}
for(int i=1;i<=n;i++)
{
memset(st,0,sizeof st);
cout<<dfs(i)-1<<'\n';
}
return 0;
}
拓扑
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx;
int d[N],cnt[N],n,m;
bitset<1005>f[N];
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
queue<int>q;
for(int i=1;i<=n;i++) if(!d[i]) q.push(i);
while(q.size())
{
int u=q.front(); q.pop();
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
f[j]|=f[u],f[j][u]=1;
if(--d[j]==0) q.push(j);
}
}
}
int main(void)
{
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--)
{
int a,b; cin>>a>>b;
add(a,b); d[b]++;
}
topsort();
for(int i=1;i<=n;i++) cout<<f[i].count()<<endl;
return 0;
}
虚空之力【贪心】
#include<bits/stdc++.h>
using namespace std;
string s1="ing";
int cnt[35],n;
string s;
int main(void)
{
cin>>n>>s;
for(int i=0;i<s.size();i++) cnt[s[i]-'a']++;
int minv=1e9;
for(int i=0;i<s1.size();i++) minv=min(minv,cnt[s1[i]-'a']);
int sum=0;
int temp=min(cnt['k'-'a'],minv/2);
sum+=temp*2;
cnt['k'-'a']-=temp,minv-=temp*2;
temp=min(cnt['k'-'a'],minv);
sum+=temp;
cout<<sum;
return 0;
}
社团游戏【前缀和】
暴力前缀和+剪枝。
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n,m,k;
int s[N][N][26];
char c[N][N];
void init(int x,int y)
{
for(int i=0;i<26;i++)
s[x][y][i]=s[x-1][y][i]+s[x][y-1][i]-s[x-1][y-1][i];
s[x][y][c[x][y]-'a']++;
}
bool check(int x,int y,int xx,int yy)
{
for(int i=0;i<26;i++)
{
int sum=s[xx][yy][i]-s[x-1][yy][i]-s[xx][y-1][i]+s[x-1][y-1][i];
if(sum>k) return false;
}
return true;
}
int main(void)
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>c[i][j];
if(k<=0)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<0<<' ';
}
cout<<'\n';
}
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) init(i,j);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int temp=min(n-i+1,m-j+1);
int ans=0;
for(int len=1;len<=temp;len++)
{
int x=i,y=j;
int xx=i+len-1,yy=j+len-1;
if(len*len<=k)
{
ans=max(ans,len);
continue;
}
if(check(x,y,xx,yy)) ans=max(ans,len);
else break;
}
cout<<ans<<' ';
}
cout<<'\n';
}
return 0;
}
前缀和+二分
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n,m,k;
int s[N][N][26];
char c[N][N];
void init(int x,int y)
{
for(int i=0;i<26;i++)
s[x][y][i]=s[x-1][y][i]+s[x][y-1][i]-s[x-1][y-1][i];
s[x][y][c[x][y]-'a']++;
}
bool check(int x,int y,int xx,int yy)
{
for(int i=0;i<26;i++)
{
int sum=s[xx][yy][i]-s[x-1][yy][i]-s[xx][y-1][i]+s[x-1][y-1][i];
if(sum>k) return false;
}
return true;
}
int main(void)
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>c[i][j];
if(k<=0)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<0<<' ';
}
cout<<'\n';
}
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) init(i,j);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int temp=min(n-i+1,m-j+1);
int l=0,r=temp;
while(l<r)
{
int mid=(l+r+1)/2;
if(check(i,j,i+mid-1,j+mid-1))l=mid;
else r=mid-1;
}
cout<<l<<' ';
}
cout<<'\n';
}
return 0;
}
名作之壁【单调栈】
逃跑路线【思维】
只需判数的奇偶即可。
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int n; cin>>n;
int ans=0;
while(n--)
{
string s; cin>>s;
int w=(s[s.size()-1]-'0');
if(w&1) ans++;
ans=ans%2;
}
cout<<ans;
return 0;
}
|