https://ac.nowcoder.com/acm/contest/4462
目录
操作序列【STL维护】
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
string s,a;
int main(void)
{
int t; cin>>t;
getline(cin,s);
while(t--)
{
getline(cin,s);
stringstream l(s);
vector<int>ve;
while(l>>a) ve.push_back(stoi(a));
if(ve.size()==1)
{
if(ve[0]==-1)
{
auto temp=mp.begin();
if(temp==mp.end()) puts("skipped");
else
{
cout<<temp->second<<'\n';
mp.erase(temp);
}
}
else
{
if(mp.count(ve[0])) cout<<mp[ve[0]]<<'\n';
else cout<<0<<'\n';
}
}else
{
bool flag=1;
for(int i=ve[0]-30;i<=ve[0]+30;i++)
if(mp.count(i)&&mp[i]>0) flag=0;
if(flag) mp[ve[0]]+=ve[1];
}
}
return 0;
}
树上子链【树的直径】
就是求树的直径,一开始想错了以为选的是类似子串那种可以选单独的中间那一块。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6*2+10;
typedef long long int LL;
LL h[N],e[N],w[N],ne[N],idx,n;
LL dist[N];
void add(int a,int b)
{
e[idx]=b,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[j]);
}
}
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i];
memset(h,-1,sizeof h);
for(int i=1;i<=n-1;i++)
{
int a,b; scanf("%d%d",&a,&b);
add(a,b),add(b,a);
}
dfs(1,-1,w[1]);
LL root=1,len=-1e12;
for(int i=1;i<=n;i++) if(len<dist[i]) len=dist[i],root=i;//找到最远的点
dfs(root,-1,w[root]);//再跑一次
len=-1e12;
for(int i=1;i<=n;i++) len=max(len,dist[i]);//取最远的就是答案。
cout<<len;
return 0;
}
交换游戏【dfs】
#include<bits/stdc++.h>
using namespace std;
int cnt;
map<string,int>mp;
void dfs(string s)
{
int temp=0;
for(int i=0;i<s.size();i++) if(s[i]=='o') temp++;
cnt=min(cnt,temp);
if(mp[s]) return;
mp[s]=1;
for(int i=2;i<s.size();i++)
{
if(s[i-2]=='-'&&s[i-1]=='o'&&s[i]=='o')
{
s[i-2]='o',s[i-1]='-',s[i]='-';
dfs(s);
s[i-2]='-',s[i-1]='o',s[i]='o';
}
if(s[i-2]=='o'&&s[i-1]=='o'&&s[i]=='-')
{
s[i-2]='-',s[i-1]='-',s[i]='o';
dfs(s);
s[i-2]='o',s[i-1]='o',s[i]='-';
}
}
}
int main(void)
{
int t; cin>>t;
while(t--)
{
cnt=12;mp.clear();
string s; cin>>s;
dfs(s);
cout<<cnt<<'\n';
}
return 0;
}
收集纸片【状压DP】
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int t,n,m,stx,sty,k,f[1<<12][15];
int dx[N],dy[N];
int get(int x,int y,int xx,int yy)
{
return abs(x-xx)+abs(y-yy);
}
int main(void)
{
cin>>t;
while(t--)
{
memset(f,0x3f,sizeof f);
cin>>n>>m>>dx[0]>>dy[0];
int z; cin>>z;
for(int i=1;i<=z;i++) cin>>dx[i]>>dy[i];
f[1][0]=0;
int cnt=z+1;
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++)
{
if(i>>k&1)
{
int temp=i-(1<<j);
if(temp>>k&1) f[i][j]=min(f[i][j],f[temp][k]+get(dx[k],dy[k],dx[j],dy[j]));
}
}
}
}
int ans=1e9;
for(int i=1;i<=z;i++) ans=min(ans,f[(1<<cnt)-1][i]+get(dx[i],dy[i],dx[0],dy[0]));
printf("The shortest path has length "),cout<<ans<<'\n';
}
return 0;
}
方块涂色【签到】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
LL n,m,r,c;
while(cin>>n>>m>>r>>c) cout<<n*m-(r*m+c*n-r*c)<<'\n';
return 0;
}
累乘数字【签到】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
LL n,d;
while(cin>>n>>d)
{
cout<<n;
for(int i=1;i<=d;i++) cout<<"00";
puts("");
}
return 0;
}
仓库选址【暴力枚举 贪心】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
struct node{
int x,y,z;};
LL get(LL x,LL y,LL xx,LL yy,LL z)
{
return z*(abs(x-xx)+abs(y-yy));
}
int main(void)
{
int t; cin>>t;
while(t--)
{
int m,n; cin>>m>>n;
vector<node>ve;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int x; cin>>x;
if(x) ve.push_back({
i,j,x});
}
LL ans=1e12;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
LL temp=0;
for(int k=0;k<ve.size();k++) temp+=get(i,j,ve[k].x,ve[k].y,ve[k].z);
ans=min(ans,temp);
}
}
cout<<ans<<'\n';
}
return 0;
}
货物种类【区间合并 差分】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
map<int,vector< pair<int,int> > >mp;
int n,m,s[N];
void add(int l,int r,int c)
{
s[l]+=c;
s[r+1]-=c;
}
int main(void)
{
cin>>n>>m;
while(m--)
{
int l,r,d; cin>>l>>r>>d;
mp[d].push_back({
l,r});
}
for(auto i=mp.begin();i!=mp.end();i++)
{
vector< pair<int,int> >ve=i->second;
vector< pair<int,int> >ans;
sort(ve.begin(),ve.end());
int l=ve[0].first,r=ve[0].second;
for(int j=1;j<ve.size();j++)//区间合并
{
if(ve[j].first>r) ans.push_back({
l,r}),l=ve[j].first,r=ve[j].second;
else r=max(r,ve[j].second);
}
ans.push_back({
l,r});
for(int j=0;j<ans.size();j++)
add(ans[j].first,ans[j].second,1);
}
int maxv=0;
for(int i=1;i<=n;i++) s[i]+=s[i-1];
for(int i=1;i<=n;i++) maxv=max(maxv,s[i]);
for(int i=1;i<=n;i++)
{
if(s[i]==maxv)
{
cout<<i;
return 0;
}
}
return 0;
}
计算A+B【高精度】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
vector<int> add(vector<int> A,vector<int> B)
{
vector<int>C;
int t=0;
for(int i=0;i<A.size()||i<B.size();i++)
{
if(i<A.size()) t+=A[i];
if(i<B.size()) t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(1);
return C;
}
int main(void)
{
int t; cin>>t;
while(t--)
{
string s; cin>>s;
int flag=1,cnt=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='+'&&!i) flag=0;
if(s[i]=='+'&&(i==s.size()-1)) flag=0;
if(s[i]=='+') cnt++;
}
if(cnt!=1) flag=0;
if(flag)
{
vector<int>A,B;
int index=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='+')
{
index=i+1;
break;
}
A.push_back(s[i]-'0');
}
reverse(A.begin(),A.end());
for(int i=s.size()-1;i>=index;i--) B.push_back(s[i]-'0');
auto C=add(A,B);
for(int i=C.size()-1;i>=0;i--) cout<<C[i];
puts("");
}else puts("skipped");
}
return 0;
}