天梯赛L3
- L3-001 凑零钱
- L3-002 特殊堆栈
- L3-003 社交集群
- L3-004 肿瘤诊断
- L3-005 垃圾箱分布
- L3-007 天梯地图
- L3-008 喊山
- L3-009 长城
- L3-010 是否完全二叉搜索树
- L3-011 直捣黄龙
- L3-012 水果忍者
- L3-013 非常弹的球
- L3-014 周游世界
- L3-015 球队“食物链”
- L3-016 二叉搜索树的结构
- L3-017 森森快递
- L3-020 至多删三个字符
- L3-021 神坛
- L3-022 地铁一日游
- L3-025 那就别担心了
- L3-028 森森旅游
- L3-029 还原文件
- L3-031 千手观音
- L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事
- L3-037 夺宝大赛
L3-001 凑零钱
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+4,M=104;
int f[M],v[N];
int pre[N][M];
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++) cin>>v[i];
sort(v,v+n,greater<int>());
for(int i=0;i<n;i++){
for(int j=m;j>=v[i];j--){
if(f[j]<=f[j-v[i]]+v[i]){//最小序,要等于号
f[j]=f[j-v[i]]+v[i];
pre[i][j]=1;
}
}
}
if(f[m]!=m){
cout<<"No Solution"<<endl;
return 0;
}
int j=m,i=n-1,flag=0;
while(i>=0&&j>=0){
if(pre[i][j]){
if(!flag) cout<<v[i],flag=1;
else cout<<" "<<v[i];
j-=v[i];
}
i--;
}
return 0;
}
L3-002 特殊堆栈
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> v;//v(N),push_back操作后v[N]==v,相当于v[0]~v[N-1]初始化为0了
stack<int> sk;
int main(){
int n,x;
string s;
cin>>n;
while(n--){
cin>>s;
if(s[1]=='u'){
cin>>x;
sk.push(x);
if(v.size()==0){
v.push_back(x);
continue;
}
auto it=lower_bound(v.begin(),v.end(),x);
v.insert(it,x);
}else if(s[1]=='o'){
if(sk.size()==0){
cout<<"Invalid"<<endl;
continue;
}
int t=sk.top();
sk.pop();
cout<<t<<endl;
auto it=lower_bound(v.begin(),v.end(),t);
v.erase(it);
}else{
if(sk.size()==0){
cout<<"Invalid"<<endl;
continue;
}
int it;
if(sk.size()&1){
it=(sk.size()+1)/2-1;
}else{
it=(sk.size()/2)-1;
}
cout<<v[it]<<endl;
}
}
return 0;
}
L3-003 社交集群
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int p[N],root[N],x,n,k,st[N];
vector<int> ans;
void init(){
for(int i=0;i<N;i++) p[i]=i;
}
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void merge(int a,int b){
int pa=find(a),pb=find(b);
if(pa!=pb){
p[pa]=pb;
}
}
int main(){
char ch[2];
cin>>n;
init();
for(int i=1;i<=n;i++){
cin>>k>>ch;
for(int j=0;j<k;j++){
cin>>x;
if(root[x]==0) root[x]=i;
merge(i,root[x]);
}
}
for(int i=1;i<=n;i++){
st[find(i)]++;
}
for(int i=1;i<=n;i++){
if(st[i]){
ans.push_back(st[i]);
}
}
sort(ans.begin(),ans.end(),greater<int>());
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++){
if(i) cout<<" "<<ans[i];
else cout<<ans[i];
}
return 0;
}
L3-004 肿瘤诊断
#include<bits/stdc++.h>
using namespace std;
int a[65][1290][135];
int m,n,l,t1,sum=0;
struct node{
int z,x,y;
};
int dx[]={0,-1,0,1,0,0},dy[]={-1,0,1,0,0,0},dz[]={0,0,0,0,-1,1};
void bfs(int sz,int sx,int sy){
int cnt=1;//要进去的时候标记然后++,不能弹出的时候,不然同一个点可能会被多次弹出,使得cnt错误
queue<node> q;
q.push({sz,sx,sy});
// auto t2=q.front();
// cout<<t2.z<<" "<<t2.x<<" "<<t2.y<<endl;
a[sz][sx][sy]=0;
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<6;i++){
int z=t.z+dz[i],x=t.x+dx[i],y=t.y+dy[i];//有段错误,指针数组越界,记得检查下标。y=t.y+dy[y]debug半天
if(z>0&&z<=l&&x>0&&x<=m&&y>0&&y<=n&&a[z][x][y]){
q.push({z,x,y});
a[z][x][y]=0;
cnt++;
}
}
}
// cout<<cnt<<endl;
if(cnt>=t1) sum+=cnt;
}
int main(){
cin>>m>>n>>l>>t1;
for(int i=1;i<=l;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=n;k++){
cin>>a[i][j][k];
}
}
}
for(int i=1;i<=l;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=n;k++){
if(a[i][j][k]){
bfs(i,j,k);
}
}
}
}
cout<<sum<<endl;
return 0;
}
L3-005 垃圾箱分布
#include<bits/stdc++.h>
using namespace std;
const int N=1050,inf=0x3f3f3f3f;
int n,m,k,ds;
int g[N][N],d[N];
bool st[N];
double ansavg=inf,anslen=-1;//初始化要注意,求avg最小则初始化很大,求最短距离最长就初始化很小
int ansid=-1;
void dj(int s){
memset(d,0x3f,sizeof d);
d[s]=0;
memset(st,false,sizeof st);
for(int i=1;i<=n+m;i++){
int t=-1;
for(int j=1;j<=n+m;j++){
if(!st[j]&&(t==-1||d[t]>d[j]))
t=j;
}
st[t]=true;
for(int j=1;j<=n+m;j++){
if(d[j]>d[t]+g[t][j]){
d[j]=d[t]+g[t][j];
}
}
}
}
int main(){
cin>>n>>m>>k>>ds;
memset(g,0x3f,sizeof g);
//fill(g[0],g[0]+N*N,0x3f3f3f3f);
memset(d,0x3f,sizeof d);
for(int i=0;i<N;i++) g[i][i]=0;
while(k--){
string a,b;
int l,t1,t2;
cin>>a>>b>>l;
if(a[0]=='G') a=a.substr(1),t1=stoi(a)+n;
else t1=stoi(a);
if(b[0]=='G') b=b.substr(1),t2=stoi(b)+n;
else t2=stoi(b);
g[t1][t2]=g[t2][t1]=l;
}
for(int ide=n+1;ide<=n+m;ide++){
dj(ide);
double avg=0;
double len=0x3f3f3f3f;//求最短距离所以初始化很大
for(int i=1;i<=n;i++){
if(d[i]>ds){
len=-1;
break;
}
if(d[i]<len) len=d[i];
avg+=1.0*d[i];
}
avg=avg/n;
if(len==-1) continue;
if(anslen<len){
anslen=len;
ansavg=avg;
ansid=ide-n;
}else if(anslen==len&&avg<ansavg){
anslen=len;
ansavg=avg;
ansid=ide-n;
}
}
if(ansid==-1){
cout<<"No Solution";
}else{
cout<<"G"<<ansid<<endl;
// cout<<ansavg<<endl;
printf("%.1lf %.1lf",anslen,ansavg);
}
return 0;
}
L3-007 天梯地图
#include<bits/stdc++.h>
using namespace std;
const int N=505,inf=0x3f3f3f3f;
int g[N][N],g1[N][N];//距离,时间
int d[N],d1[N];//距离,时间
int dis[N],num[N];
int n,m;
int sta,ed;
bool st[N],st1[N];
vector<int> v,v1;
int pre[N],pre1[N];
void serv(int pre[],vector<int> &v){
int t=ed;
while(t!=sta){
v.push_back(t);
t=pre[t];
}
v.push_back(sta);
}
void dj(){//距离
memset(d,0x3f,sizeof d);
memset(num,0x3f,sizeof num);
d[sta]=0;
num[sta]=1;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++){
if(!st[j]&&(t==-1||d[j]<d[t]))
t=j;
}
st[t]=true;
for(int j=0;j<n;j++){
// if(d[j]>d[t]+g[t][j]){
// d[j]=d[t]+g[t][j];
// num[j]=num[t]+1;
// pre[j]=t;
// }else if(d[j]==d[t]+g[t][j]&&num[j]>num[t]+1){//不能num[j]<num[t]+1判断,因为num初始都是0。
// d[j]=d[t]+g[t][j];
// num[j]=num[t]+1;
// pre[j]=t;
// }
if(d[j]>d[t]+g[t][j]||(d[j]==d[t]+g[t][j]&&num[j]>num[t]+1)){
d[j]=d[t]+g[t][j];
num[j]=num[t]+1;
pre[j]=t;
}
}
}
serv(pre,v);
}
void dj1(){//时间
memset(d1,0x3f,sizeof d1);
d1[sta]=0;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++){
if(!st1[j]&&(t==-1||d1[j]<d1[t]))
t=j;
}
st1[t]=true;
for(int j=0;j<n;j++){
if(d1[j]>d1[t]+g1[t][j]){
d1[j]=d1[t]+g1[t][j];
dis[j]=dis[t]+g[t][j];
pre1[j]=t;
}else if(d1[j]==d1[t]+g1[t][j]&&dis[j]>dis[t]+g[t][j]){
d1[j]=d1[t]+g1[t][j];
dis[j]=dis[t]+g[t][j];
pre1[j]=t;
}
}
}
serv(pre1,v1);
}
int main(){
cin>>n>>m;
memset(g,0x3f,sizeof g);
memset(g1,0x3f,sizeof g1);
while(m--){
int a,b,c,d,e;
cin>>a>>b>>c>>d>>e;
if(c==1){
g[a][b]=d;
g1[a][b]=e;
}else{
g[a][b]=g[b][a]=d;
g1[a][b]=g1[b][a]=e;
}
}
cin>>sta>>ed;
dj(),dj1();
if(v==v1){
printf("Time = %d; Distance = %d: %d",d1[ed],d[ed],v1[v1.size()-1]);
for(int i=v1.size()-2;i>=0;i--){
cout<<" => "<<v1[i];
}
}else{
printf("Time = %d: %d",d1[ed],v1[v1.size()-1]);
for(int i=v1.size()-2;i>=0;i--){
cout<<" => "<<v1[i];
}
cout<<endl;
printf("Distance = %d: %d",d[ed],v[v.size()-1]);
for(int i=v.size()-2;i>=0;i--){
cout<<" => "<<v[i];
}
}
return 0;
}
L3-008 喊山
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
typedef pair<int,int> pii;
int n,m,k;
vector<int> v[N];//小括号是一维初始化,中括号是二维数组
bool st[N];
int bfs(int x){
memset(st,false,sizeof st);
int ansid=10010,ansh=0;
queue<pii> q;
q.push({x,1});
st[x]=true;//进去就标记不要忘记了
while(q.size()){
auto t=q.front();
q.pop();
int var=t.first,hg=t.second;
// cout<<var<<" "<<hg<<endl;
if(ansh<hg){
ansh=hg;
ansid=var;
}else if(ansh==hg){
ansid=min(ansid,var);
}
for(auto i:v[var]){
if(!st[i]){
q.push({i,hg+1});
st[i]=true;
}
}
}
// cout<<"hh"<<endl;
return ansid;
}
int main(){
cin>>n>>m>>k;
while(m--){
int a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
while(k--){
int x;cin>>x;
if(v[x].size()==0) cout<<"0"<<endl;
else cout<<bfs(x)<<endl;
}
return 0;
}
L3-009 长城
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
long long stk[N],tt,n,x[N],y[N];//记得开long long,两个数相乘
bool st[N];
bool check(int l,int mid,int r){
return (y[r]-y[l])*(x[mid]-x[l])>=(y[mid]-y[l])*(x[r]-x[l]);
}
int main(){
cin>>n;
int ans=0;
for(int i=0;i<n;i++){
cin>>x[i]>>y[i];
if(tt){
while(tt>1&&check(i,stk[tt],stk[tt-1])){
tt--;
}
if(tt!=1&&!st[stk[tt]]){
ans++;
st[stk[tt]]=true;
}
}
stk[++tt]=i;
}
cout<<ans<<endl;
return 0;
}
L3-010 是否完全二叉搜索树
#include<bits/stdc++.h>
using namespace std;
const int N=1<<20;
int n,t,tree[N];
void build(int x){
if(tree[x]==0)
tree[x]=t;
else if(tree[x]<t){
build(x<<1);
}else{
build(x<<1|1);
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>t;
build(1);
}
bool flag=false;
for(int cnt=1,k=1;cnt<=n;k++){
if(tree[k]==0){
flag=true;
}else{
cout<<tree[k];
cout<<(cnt++!=n?" ":"");
}
}
cout<<endl;
if(flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
return 0;
}
L3-011 直捣黄龙
#include<bits/stdc++.h>
using namespace std;
const int N=501,inf=0x3f3f3f3f;
int g[N][N];
string sta,ed;
int edd;
int d[N],num[N],sum[N],enemy[N],cnt[N];//距离,节点数,总敌人数,每个点敌人数,最短路径方案数
int pre[N];
bool st[N];
vector<string> v;
map<string,int> sti;
map<int,string> its;
int idx=1;
int n,k;
void serv(int pre[]){
int p=edd;
while(p!=0){
v.push_back(its[p]);
p=pre[p];
}
v.push_back(its[0]);
}
void dj(){
memset(d,0x3f,sizeof d);
d[0]=0;
cnt[0]=1;
for(int i=0;i<n;i++){
int t=-1;
for(int j=0;j<n;j++){
if(!st[j]&&(t==-1||d[j]<d[t]))
t=j;
}
st[t]=true;
for(int j=0;j<n;j++){
if(d[j]>d[t]+g[t][j]){
d[j]=d[t]+g[t][j];
num[j]=num[t]+1;
sum[j]=sum[t]+enemy[j];
cnt[j]=cnt[t];
pre[j]=t;
}else if(d[j]==d[t]+g[t][j]){
cnt[j]+=cnt[t];//单纯的当d[j]==d[t]+g[t][j]相等的时候路径数量就得加
//if(d[j]==d[t]+g[t][j]&&num[j]<num[t]+1)
//或者if(d[j]==d[t]+g[t][j]&&num[j]==num[t]+1&&sum[t]<sum[t]+enemy[j])的时候加cnt[j]+=cnt[t]不行
//cnt是单纯的路径长度相等加,例如当路径长度,节点数,总敌人数都一样的时候也得更新路径条数。
if(num[j]<num[t]+1){//尽量多的点就<
num[j]=num[t]+1;
sum[j]=sum[t]+enemy[j];
pre[j]=t;
}else if(num[j]==num[t]+1&&sum[j]<sum[t]+enemy[j]){
sum[j]=sum[t]+enemy[j];
pre[j]=t;
}
}
}
}
serv(pre);
}
int main(){
memset(g,0x3f,sizeof g);
// for(int i=0;i<N;i++) g[i][i]=0;
cin>>n>>k>>sta>>ed;
string a,b;
int x,le;
for(int i=0;i<n-1;i++){
cin>>a>>x;
sti[a]=idx;
its[idx]=a;
enemy[sti[a]]=x;
idx++;
}
// n=idx;
// cout<<n<<endl;
sti[sta]=0,its[0]=sta,edd=sti[ed];
while(k--){
cin>>a>>b>>le;
g[sti[a]][sti[b]]=g[sti[b]][sti[a]]=le;
}
dj();
for(int i=v.size()-1;i>=0;i--){
cout<<(i==v.size()-1?"":"->")<<v[i];
}
cout<<endl<<cnt[edd]<<" "<<d[edd]<<" "<<sum[edd]<<endl;
return 0;
}
L3-012 水果忍者
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10,inf=0x3f3f3f3f;
double mxk,mnk,tmxk,tmnk;
struct node{
double x,y1,y2;//要用double类型,不然会损失精度
bool operator<(const node& w) const{
return x<w.x;
}
}f[N];
int n,ansx,ansy;
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>f[i].x>>f[i].y1>>f[i].y2;
}
sort(f,f+n);
for(int i=0,j;i<n;i++){
mxk=inf,mnk=-inf;//根据j内的进行收缩
for(j=0;j<n;j++){
if(i==j) continue;
if(i<j){
tmxk=(f[j].y1-f[i].y2)/(f[j].x-f[i].x);
tmnk=(f[j].y2-f[i].y2)/(f[j].x-f[i].x);
}else{
tmxk=(f[i].y2-f[j].y2)/(f[i].x-f[j].x);
tmnk=(f[i].y2-f[j].y1)/(f[i].x-f[j].x);
}
if(tmnk>mxk||mnk>tmxk) break;
if(tmxk<mxk){
mxk=tmxk;
ansx=f[j].x;
ansy=f[j].y1;
}
mnk=max(mnk,tmnk);
}
if(j==n){
//以i为基点的下面那个点,j找上面那个点,y1>y2
cout<<ansx<<" "<<ansy<<" "<<(int)f[i].x<<" "<<(int)f[i].y2;
break;
}
}
return 0;
}
L3-013 非常弹的球
#include<bits/stdc++.h>
using namespace std;
int main(){
double w,p,v2,s=0;
cin>>w>>p;
p=(100-p)/100;
v2=2*1000*100/w;
while(v2>1e-6){
s+=v2/9.8;//动能转换为重力势能,h
v2=v2*p;
}
printf("%.3lf",s);
return 0;
}
L3-014 周游世界
DFS解法
#include<bits/stdc++.h>
using namespace std;
const int N=10005;
vector<vector<int> > v(N);
int line[N][N],st[N];
vector<int> path,tpath;
int transfer(vector<int> t){
int cnt=-1,preline=0;
for(int i=1;i<t.size();i++){
if(line[t[i-1]][t[i]]!=preline){
cnt++;
}
preline=line[t[i-1]][t[i]];
}
return cnt;
}
void dfs(int node,int ed,int cnt,int &mincnt,int &mintransfer){//注意带引用符
if(node==ed&&(cnt<mincnt||(cnt==mincnt&&transfer(tpath)<mintransfer))){
mincnt=cnt;
mintransfer=transfer(tpath);
path=tpath;
}
if(node==ed) return;
for(int i=0;i<v[node].size();i++){
if(!st[v[node][i]]){
st[v[node][i]]=1;
tpath.push_back(v[node][i]);
dfs(v[node][i],ed,cnt+1,mincnt,mintransfer);
st[v[node][i]]=0;
tpath.pop_back();
}
}
}
int main(){
int n,m,k,pre,temp,a,b;
cin>>n;
for(int i=1;i<=n;i++){
cin>>m>>pre;
for(int j=1;j<m;j++){
cin>>temp;
line[pre][temp]=line[temp][pre]=i;
v[pre].push_back(temp);
v[temp].push_back(pre);
pre=temp;
}
}
cin>>k;
while(k--){
int mincnt=99999,mintransfer=99999;
cin>>a>>b;
tpath.clear();
tpath.push_back(a);
st[a]=1;
dfs(a,b,0,mincnt,mintransfer);
st[a]=0;
if(mincnt==99999){
cout<<"Sorry, no line is available."<<endl;
continue;
}
cout<<mincnt<<endl;
int preline=0,pretransfer=a;
for(int j=1;j<path.size();j++){
if(line[path[j-1]][path[j]]!=preline){
if(preline!=0) printf("Go by the line of company #%d from %04d to %04d.\n",preline,pretransfer,path[j-1]);
preline=line[path[j-1]][path[j]];
pretransfer=path[j-1];
}
}
printf("Go by the line of company #%d from %04d to %04d.\n",preline,pretransfer,b);
}
}
最短路解法
#include<bits/stdc++.h>
using namespace std;
const int N=10005,M=100*N;
typedef pair<int,int> pii;
int h[N],e[M],ne[M],com[M],step[M],idx;//company
int d[N],cnt[N],s[N],pre[N];//距离最短为第一排序条件,中转最少为第二条件
bool st[N];
string node[N];
void add(int a,int b,int len,int i){
e[idx]=b,ne[idx]=h[a],step[idx]=len,com[idx]=i,h[a]=idx++;
}
string get_num(int t){
string s=to_string(t);
while(s.size()<4) s="0"+s;
return s;
}
void dj(int src,int des){
memset(d,0x3f,sizeof d);
memset(cnt,0x3f,sizeof cnt);
memset(st,false,sizeof st);
d[src]=cnt[src]=0;
priority_queue<pii,vector<pii>,greater<pii> > q;
q.push({0,src});
while(q.size()){
auto t=q.top();q.pop();
int dis=t.first,ver=t.second;
if(st[ver]) continue;
st[ver]=true;
for(int i=h[ver];~i;i=ne[i]){
int j=e[i];
if(d[j]>d[ver]+step[i]){
d[j]=d[ver]+step[i];
if(com[ver]!=com[i]){
cnt[j]=cnt[ver]+1;
}
pre[j]=ver;
//从点ver到点j的路径,com[i]不同的idx则不同。
node[j]="Go by the line of company #"+to_string(com[i])+" from "+get_num(ver)+" to "+get_num(j)+".";
q.push({d[j],j});
}else if(d[j]==d[ver]+step[i]&&cnt[j]>cnt[ver]+1){
cnt[j]=cnt[ver]+1;
pre[j]=ver;
node[j]="Go by the line of company #"+to_string(com[i])+" from "+get_num(ver)+" to "+get_num(j)+".";
}
}
}
if(d[des]==0x3f3f3f3f){
cout<<"Sorry, no line is available."<<endl;
return;
}
cout<<d[des]<<endl;
vector<string> ans;
int p=des;
while(p!=src){
ans.push_back(node[p]);
p=pre[p];
}
// ans.push_back(node[p]);
for(int i=ans.size()-1;i>=0;i--){
cout<<ans[i]<<endl;
}
return;
}
int main(){
memset(h,-1,sizeof h);
int n,m,k;
cin>>n;
for(int i=1;i<=n;i++){
cin>>m;
for(int j=1;j<=m;j++) cin>>s[j];
for(int j=1;j<=m;j++){
for(int k=j+1;k<=m;k++){
int dis=k-j;
if(s[1]==s[k]) dis=min(dis,k-dis-1);//环形的,一共k个点,dis为两点之间的距离,k-dis-1为另一条路线的dis为两点之间的距离
add(s[j],s[k],dis,i),add(s[k],s[j],dis,i);
}
}
}
cin>>k;
while(k--){
int a,b;cin>>a>>b;
dj(a,b);
}
return 0;
}
L3-015 球队“食物链”
#include<bits/stdc++.h>
using namespace std;
const int N=25;
int v[N][N],n;
int ans[N];
bool flag,st[N];
void dfs(int index,int num){//ans[index]=num在第index位置放数num球队
if(flag==1) return;
ans[index]=num;
if(index==n&&v[num][1]){
flag=1;
return;
}
if(index==n) return;
bool cut=false;
for(int i=1;i<=n;i++){
if(!st[i]&&v[i][1]){
cut=true;
break;
}
}
if(!cut) return;//剩下球队没有能打败球队1的队伍,直接退出,不满足条件
st[num]=true;
for(int i=1;i<=n;i++){
if(!st[i]&&v[num][i]){
dfs(index+1,i);
}
}
st[num]=false;
}
int main(){
cin>>n;
char s[N];
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=n;j++){
if(s[j]=='W') v[i][j]=1;
if(s[j]=='L') v[j][i]=1;
}
}
dfs(1,1);
if(flag){
for(int i=1;i<=n;i++){
cout<<(i==1?"":" ")<<ans[i];
}
}else{
cout<<"No Solution";
}
return 0;
}
L3-016 二叉搜索树的结构
#include <bits/stdc++.h>
using namespace std;
struct node {
int num, lchild, rchild, parent, level;
node() {
lchild = rchild = parent = -1;
}
}Tree[128];
int n, m, a, b, in, cnt, root = 1, f;
map<int, int> Find;
string t;
void insert(int x) {
int now = root;
while(Tree[now].num != x) {
if (x < Tree[now].num) {
if (Tree[now].lchild == -1) {
Tree[cnt].num = x;
Tree[cnt].level = Tree[now].level + 1;
Tree[cnt].parent = now;
Tree[now].lchild = cnt;
}
now = Tree[now].lchild;
} else {
if (Tree[now].rchild == -1) {
Tree[cnt].num = x;
Tree[cnt].level = Tree[now].level + 1;
Tree[cnt].parent = now;
Tree[now].rchild = cnt;
}
now = Tree[now].rchild;
}
}
}
int main() {
cin >> n >> in;
Tree[++cnt].num = in;
Find[in] = cnt;
for (int i = 1; i < n; i++) {
cin >> in;
Find[in] = ++cnt;
insert(in);
}
cin >> m;
while (m--) {
f = 0;
cin >> a >> t;
if (t == "is") {
cin >> t >> t;
if (t == "root") {
if (Find[a] == root) f = 1;
} else if (t == "parent") {
cin >> t >> b;
if (Tree[Find[b]].parent == Find[a]) f = 1;
} else if (t == "left") {
cin >> t >> t >> b;
if (Tree[Find[b]].lchild == Find[a]) f = 1;
} else {
cin >> t >> t >> b;
if (Tree[Find[b]].rchild == Find[a]) f = 1;
}
} else {
cin >> b >> t >> t;
if (t == "siblings") {
if (Find[a] && Find[b] && Tree[Find[a]].parent == Tree[Find[b]].parent) f = 1;
} else {
cin >> t >> t >> t;
if (Find[a] && Find[b] && Tree[Find[a]].level == Tree[Find[b]].level) f = 1;
}
}
cout << (f ? "Yes" : "No") << '\n';
}
return 0;
}
L3-017 森森快递
#include<bits/stdc++.h>
using namespace std;
#define lc p<<1
#define rc p<<1|1
#define debug(x) cout<<#x<<" = "<<x<<endl
#define int long long
typedef long long ll;
const int N=1e5+10;
int n,q,x,w[N],ans;
struct node{
int l,r,var,add;
}tr[4*N];
struct eg{
int l,r;
bool operator<(const eg&w) const{
if(r!=w.r) return r<w.r;
return l>w.l;
}
}e[N];
void pushup(int p){
tr[p].var=min(tr[lc].var,tr[rc].var);
}
void pushdown(int p){
if(tr[p].add){
tr[lc].var+=tr[p].add;
tr[rc].var+=tr[p].add;
tr[lc].add+=tr[p].add;
tr[rc].add+=tr[p].add;
tr[p].add=0;
}
}
void build(int p,int l,int r){
tr[p]={l,r,w[l],0};
if(l==r) return;
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
pushup(p);
}
void update(int p,int x,int y,int k){
if(x<=tr[p].l&&tr[p].r<=y){
tr[p].var+=k;
tr[p].add+=k;
return;
}
int m=tr[p].l+tr[p].r>>1;
pushdown(p);
if(x<=m) update(lc,x,y,k);
if(y>m) update(rc,x,y,k);
pushup(p);
}
int query(int p,int x,int y){
if(x<=tr[p].l&&tr[p].r<=y){
return tr[p].var;
}
int m=tr[p].l+tr[p].r>>1;
pushdown(p);
int ans=0x3f3f3f3f3f3f3f3f;
if(x<=m) ans=min(ans,query(lc,x,y));
if(y>m) ans=min(ans,query(rc,x,y));
return ans;
}
signed main(){
cin>>n>>q;
for(int i=1;i<=n-1;i++) cin>>w[i];
build(1,1,n-1);
for(int i=1;i<=q;i++){
int l,r;cin>>l>>r;
if(l>r) swap(l,r);
e[i]={l,r};
}
sort(e+1,e+1+q);
for(int i=1;i<=q;i++){
int l=e[i].l+1,r=e[i].r;
int num=query(1,l,r);
if(num>0){
ans+=num;
update(1,l,r,-num);
}
}
cout<<ans<<endl;
return 0;
}
L3-020 至多删三个字符
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
#define int long long
typedef long long ll;
char s[N];
int f[N][4];//内存最好不要多开,4换成10就会内存超限
signed main(){
cin>>s+1;
int len=strlen(s+1);
for(int i=0;i<=len;i++) f[i][0]=1;
for(int i=1;i<=len;i++){
for(int j=1;j<=3;j++){
f[i][j]=f[i-1][j]+f[i-1][j-1];
for(int k=i-1;k&&(i-k)<=j;k--){
if(s[i]==s[k]){
f[i][j]-=f[k-1][j-(i-k)];
break;//这个不要忘记
}
}
}
}
ll ans=f[len][0]+f[len][1]+f[len][2]+f[len][3];
cout<<ans;
return 0;
}
L3-021 神坛
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
typedef long long ll;
ll ans=1e17;
int n,i,cnt;
typedef pair<ll,ll> pll;
bool cmp(pll a,pll b){
if(a.first*b.second!=b.first*a.second){
return a.first*b.second>a.second*b.first;
}
return a.first<b.first;
}
int main(){
cin>>n;
vector<pll> a(n),b(n-1);
for(int i=0;i<n;i++) cin>>a[i].first>>a[i].second;
for(int i=0;i<n;i++,cnt=0){
for(int j=0;j<n;j++){
if(i==j) continue;
b[cnt++]={a[j].first-a[i].first,a[j].second-a[i].second};
}
sort(b.begin(),b.end(),cmp);
for(int j=1;j<n-1;j++) ans=min(ans,abs(b[j-1].first*b[j].second-b[j].first*b[j-1].second));
}
printf("%.3lf",0.5*ans);
return 0;
}
L3-022 地铁一日游
#include<bits/stdc++.h>
using namespace std;
const int N=2050,M=60000,inf=0x3f3f3f3f;
typedef long long ll;
int n,m,k,cnt,x,tot;
int flag[M];
int t[M],d[N][N];
int g[N][N];
string s;
bool st[N];
set<int> se;
void floyed(){
for(int i=1;i<=n;i++) d[i][i]=0;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
void dfs(int u){
st[u]=1;
se.insert(u);
for(int v=1;v<=n;v++){
if(!st[v]&&g[u][v]){
dfs(v);
}
}
}
int main(){
cin>>n>>m>>k;
memset(d,0x3f,sizeof d);
getchar();
while(m--){
getline(cin,s);
stringstream ss;
ss<<s;
cnt=0;//chushihua
while(ss>>s){
t[++cnt]=stoi(s);
}
for(int i=1;i<cnt;i+=2){
int a=t[i],b=t[i+2],c=t[i+1];
if(i==1) flag[a]=1;
if(i==cnt-2) flag[b]=1;//这个地方的tot没有换成cnt过不了三个测试点
d[b][a]=d[a][b]=min(d[a][b],c);
}
}
floyed();
for(int i=1;i<=n;i++){
map<int,int> mp;
for(int j=1;j<=n;j++){
if(d[i][j]==inf) continue;
int p=d[i][j]/k;
mp[p]=max(mp[p],d[i][j]);
}
for(int j=1;j<=n;j++){
int p=d[i][j]/k;
if(i==j||d[i][j]==inf) continue;
if(flag[j]||d[i][j]==mp[p]) g[i][j]=1;
}
g[i][i]=1;
}
cin>>m;
while(m--){
memset(st,false,sizeof st);
se.clear();
cin>>x;
dfs(x);
cout<<*se.begin();
se.erase(*se.begin());
for(auto x:se){
cout<<" "<<x;
}
cout<<endl;
}
return 0;
}
L3-025 那就别担心了
#include<bits/stdc++.h>
using namespace std;
const int N=510;
bool flag;
int num[N];
int n,m;
vector<int> v[N];
int dfs(int u){
if(num[u]) return num[u];
for(auto x:v[u]){
if(num[x]==0)
dfs(x);
num[u]+=num[x];//bunengfangdaoifxunhuannei
}
if(num[u]==0) flag=true;
return num[u];
}
int main(){
cin>>n>>m;
while(m--){
int a,b;cin>>a>>b;
v[a].push_back(b);
}
int a,b;
cin>>a>>b;
num[b]=1;
dfs(a);
cout<<num[a]<<" "<<(flag?"No":"Yes");
return 0;
}
L3-028 森森旅游
#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" = "<<x<<endl
#define int long long
using namespace std;
typedef long long ll;
typedef pair<ll,int> pli;
const ll N=1e6 ,inf=0x3f3f3f3f3f3f3f3f;
int e[N],ne[N],h[N],rh[N],w[N],idx;
ll d1[N],d2[N],a[N];//记得long long
bool st[N];
void add(int h[],int a,int b,int c){
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
int n,m,q,u,v,c,d;
multiset<ll> se;
void dj(int h[],int s,ll d[]){
memset(d,0x3f,sizeof d1);//不能是sizeof d,因为d只是个形参,表示数组第一个元素
memset(st,0,sizeof st);
// fill(d,d+N,inf);
// fill(st,st+N,0);
d[s]=0;
priority_queue<pli,vector<pli>,greater<pli> > q;
q.push({0,s});
while(q.size()){
auto t=q.top().second;
q.pop();
if(st[t]) continue;
st[t]=true;
for(int i=h[t];~i;i=ne[i]){
int j=e[i];
if(d[j]>d[t]+w[i]){
d[j]=d[t]+w[i];
q.push({d[j],j});
}
}
}
return;
}
signed main(){
memset(h,-1,sizeof h);
memset(rh,-1,sizeof rh);
cin>>n>>m>>q;
while(m--){
cin>>u>>v>>c>>d;
add(h,u,v,c),add(rh,v,u,d);
}
for(int i=1;i<=n;i++) cin>>a[i];
dj(h,1,d1),dj(rh,n,d2);
// for(int i=1;i<=n;i++) debug(d1[i]);
// cout<<endl;
// for(int i=1;i<=n;i++) debug(d2[i]);
for(int i=1;i<=n;i++){
if(d1[i]==inf||d2[i]==inf) continue;
ll p=d1[i]+(d2[i]+a[i]-1)/a[i];
se.insert(p);
}
while(q--){
int x,y;cin>>x>>y;
if(d1[x]==inf||d2[x]==inf){//两个一个到不了都不行
cout<<*se.begin()<<endl;
continue;
}
ll p=d1[x]+(d2[x]+a[x]-1)/a[x];
se.erase(se.find(p));
a[x]=y;
p=d1[x]+(d2[x]+a[x]-1)/a[x];
se.insert(p);
cout<<*se.begin()<<endl;
}
return 0;
}
L3-029 还原文件
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,k,t,flag1,flag2;
int h[N],st[N];
vector<int> ans,temp[101];
void dfs(int p){
if(ans.size()==m){
flag1=true;
for(int i=0;i<m;i++){
if(i) cout<<" ";
cout<<ans[i];
}
}
if(flag1) return;
for(int i=1;i<=m;i++){
if(st[i]) continue;
flag2=0;
for(int j=0;j<temp[i].size();j++){
if(temp[i][j]!=h[p+j]){
flag2=true;
break;
}
}
if(flag2) continue;
ans.push_back(i);
st[i]=true;
dfs(p+temp[i].size()-1);
st[i]=false;
ans.pop_back();
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++) cin>>h[i];
cin>>m;
for(int i=1;i<=m;i++){
cin>>k;
for(int j=0;j<k;j++){
cin>>t;
temp[i].push_back(t);
}
}
dfs(0);
return 0;
}
L3-031 千手观音
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
unordered_map<string,int> d;
unordered_map<string,vector<string>> g;
vector<string> get(string str){
vector<string> res;
string word;
for(auto &c:str){
if(c=='.'){
res.push_back(word);
if(!d.count(word)) d[word]=0;
word="";
}
else word+=c;
}
res.push_back(word);
if(!d.count(word)) d[word]=0;
return res;
}
vector<string> topsort(){
priority_queue<string,vector<string>,greater<string> > q;
for(auto &[k,v]:d)
if(!v)
q.push(k);
vector<string> res;
while(q.size()){
string t=q.top();q.pop();
res.push_back(t);
for(auto &p:g[t])
if(--d[p]==0){
q.push(p);
}
}
return res;
}
int main(){
ios::sync_with_stdio(false);
int n;cin>>n;
string str;cin>>str;
vector<string> last=get(str);
for(int i=0;i<n-1;i++){
cin>>str;
vector<string> cur=get(str);
if(last.size()==cur.size()){
for(int j=0;j<cur.size();j++)
if(last[j]!=cur[j]){
g[last[j]].push_back(cur[j]);
d[cur[j]]++;//入度
break;
}
}
last=cur;
}
vector<string> res=topsort();
cout<<res[0];
for(int i=1;i<res.size();i++)
cout<<"."<<res[i];
return 0;
}
L3-032 关于深度优先搜索和逆序对的题应该不会很难吧这件事
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10,p=1e9+7;
vector<int> g[N];
int sz[N],tr[N];
int n,root;
int sum=1,s1,s2;
void add(int x,int y){
for(int i=x;i<N;i+=(i&-i))
tr[i]+=y;
}
int query(int x){
int res=0;
for(int i=x;i;i-=(i&-i))
res+=tr[i];
return res;
}
void dfs(int u,int fa){
add(u,1);
s1=(s1+query(n)-query(u))%p;
sz[u]=1;
int cnt=0;
for(auto &j:g[u]){
if(j==fa) continue;
dfs(j,u);
sz[u]+=sz[j];
cnt++;
}
for(int i=1;i<=cnt;i++)
sum=(ll)sum*i%p;
s2=(s2+n-query(n)-sz[u]+1)%p;
add(u,-1);
}
int main(){
cin>>n>>root;
for(int i=0;i<n-1;i++){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(root,-1);
int ans=((ll)s1*sum+(ll)s2*sum%p*(p+1)/4)%p;
cout<<ans;
return 0;
}
L3-037 夺宝大赛
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N=110;
int g[N][N];
typedef pair<int,int> pii;
int n,m;
int ax,ay,d[N][N];
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
bool st[N][N];
vector<pii> ve;//或者直接用vector<vector<int>>
multiset<int> s;
void bfs(int x,int y){
queue<pii> q;
q.emplace(x,y);
memset(d,0x3f,sizeof d);
d[x][y]=0;
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int tx=t.x+dx[i],ty=t.y+dy[i];
if(tx<1||tx>n||ty<1||ty>m||g[tx][ty]==0) continue;
if(d[tx][ty]>d[t.x][t.y]+1){
d[tx][ty]=d[t.x][t.y]+1;
q.emplace(tx,ty);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>g[i][j];
if(g[i][j]==2){
ax=i,ay=j;
}
}
}
int q;cin>>q;
bfs(ax,ay);
for(int i=0;i<q;i++){
int x,y;
cin>>y>>x;
ve.emplace_back(d[x][y],i+1);
s.insert(d[x][y]);
}
sort(ve.begin(),ve.end());
bool f=false;
for(int i=0;i<ve.size();i++){
int dis=ve[i].x,id=ve[i].y;
if(s.count(dis)==1&&dis!=0x3f3f3f3f){
cout<<id<<" "<<dis<<endl;
f=true;
break;
}
}
if(!f) cout<<"No winner.";
return 0;
}