天梯赛L2

L2-001 紧急救援

在这里插入图片描述
最短路径模板题
1.最短路径求法dist,st,g
2.不同的需求可以开不同的数组来表示,救援sum,cnt
3.求最短路径的个数num和最短路径的过程pre

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
int g[N][N];
int dist[N];
bool st[N];
int pre[N],sum[N],cn[N],num[N];//路径,总共救援队,每个城市救援队,最短路劲条数
int n,m,s,d;

void dj(){
    memset(dist,0x3f,sizeof dist);
    dist[s]=0;
    sum[s]=cn[s];
    num[s]=1;
    for(int i=0;i<n;i++){
        int t=-1;
        for(int j=0;j<n;j++)
            if(!st[j]&&(t==-1||dist[j]<dist[t])){//此处有点不记得了,找没有被标记且离源点最近的点,不用加g[t][j]
                t=j;
            }
        st[t]=true;
        for(int j=0;j<n;j++){
            if(dist[j]>dist[t]+g[t][j]){
                dist[j]=dist[t]+g[t][j];
                sum[j]=sum[t]+cn[j];
                pre[j]=t;
                num[j]=num[t];
            }
            else if(dist[j]==dist[t]+g[t][j]){
                num[j]+=num[t];
                if(sum[j]<sum[t]+cn[j]){
                    sum[j]=sum[t]+cn[j];
                    pre[j]=t;
                }
            }
        }
    }
    
}

int main(){
    cin>>n>>m>>s>>d;
    for(int i=0;i<n;i++)
        cin>>cn[i];
    memset(g,0x3f,sizeof g);
    while(m--){
        int a,b,c;
        cin>>a>>b>>c;
        g[a][b]=g[b][a]=c;
    }
    dj();
    cout<<num[d]<<" "<<sum[d]<<endl;
    vector<int> ve;
    int fa=d;
    while(fa!=s){
        ve.push_back(fa);
        fa=pre[fa];
    }
    ve.push_back(s);
    for(int i=ve.size()-1;i>=0;i--){
        if(i==0) cout<<ve[i];
        else cout<<ve[i]<<" ";
    }
    return 0;
}

L2-002 链表去重

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
struct node{
    int data,next;
}a[N];

int main(){
    int first,n;
    cin>>first>>n;
    set<int> s;
    int del[N],pre[N];
    int k1=0,k2=0;
    for(int i=0;i<n;i++){
        int ad;
        cin>>ad;
        cin>>a[ad].data>>a[ad].next;
    }
    int i=first;
    while(a[i].next!=-1){
        int num=abs(a[i].data);
        if(s.count(num)){
            del[k1++]=i;
        }else{
            pre[k2++]=i;
            s.insert(num);
        }
        i=a[i].next;
    }
    //最后一个指向-1的节点不要忘记了
    int num=abs(a[i].data);
    if(s.count(num)){
        del[k1++]=i;
    }else pre[k2++]=i;
    
    // cout<<k2<<endl;
    printf("%05d %d ",pre[0],a[pre[0]].data);
    for(int j=1;j<k2;j++){
        printf("%05d\n",pre[j]);
        printf("%05d %d ",pre[j],a[pre[j]].data);
    }
    cout<<"-1"<<endl;
    // cout<<k1<<endl;
    if(k1){
        printf("%05d %d ",del[0],a[del[0]].data);
        for(int j=1;j<k1;j++){
            printf("%05d\n",del[j]);
            printf("%05d %d ",del[j],a[del[j]].data);
        }
        cout<<"-1"<<endl;
    }
    return 0;
}

L2-003 月饼

在这里插入图片描述

结构体排序

#include<bits/stdc++.h>
using namespace std;
struct node{
    double n,p;//库存,售价
}a[1010];

bool cmp(node a,node b){
    return a.p*b.n>a.n*b.p;
}

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>a[i].n;
    for(int i=0;i<n;i++)
        cin>>a[i].p;
    sort(a,a+n,cmp);
    double ans=0;
    for(int i=0;i<n&&m;i++){
        if(a[i].n<m){
            m-=a[i].n;
            ans+=a[i].p;
        }else{
            ans+=(a[i].p/a[i].n*m);
            m=0;
        }
    }
    printf("%.2lf",ans);
    return 0;
}

L2-004 这是二叉搜索树吗?

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n;
int pr[N];//前序遍历
vector<int> pa;//后序遍历
bool flag;
void find(int l,int r){
    if(l>r) return;
    int tl=l+1,tr=r;
    if(!flag){
        while(tl<=r&&pr[tl]<pr[l]) tl++;
        while(tr>l&&pr[tr]>=pr[l]) tr--;
    }
    else{
        while(tl<=r&&pr[tl]>=pr[l]) tl++;
        while(tr>l&&pr[tr]<pr[l]) tr--;
    }
    if(tl-tr!=1) return;
    find(l+1,tr);
    find(tl,r);
    pa.push_back(pr[l]);
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>pr[i];
    find(0,n-1);
    if(pa.size()!=n){
        pa.clear();
        flag=true;
        find(0,n-1);
    }
    if(pa.size()!=n) cout<<"NO"<<endl;
    else{
        cout<<"YES"<<endl;
        for(int i=0;i<pa.size();i++)
            if(i) cout<<" "<<pa[i];
            else cout<<pa[i];
    }
    return 0;
}

L2-005 集合相似度

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int n,m,k,x;
vector<set<int>> a(N);//不能用中括号 

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>m;
        set<int> t;
        for(int i=0;i<m;i++){
            cin>>x;
            t.insert(x);
        }
        a[i]=t;
    }
    cin>>k;
    for(int i=0;i<k;i++){
        int b,c,cnt=0;
        cin>>b>>c;
        for(auto itm:a[b]){
            if(a[c].find(itm)!=a[c].end())//需要写!= 
                cnt++;
        }
        double ans=1.0*cnt/(a[b].size()+a[c].size()-cnt)*100;
        printf("%.2lf%%\n",ans);
    }
    return 0;
}

L2-006 树的遍历

在这里插入图片描述
根据中序遍历和后序遍历建树,然后用bfs求层次遍历

#include<bits/stdc++.h>
using namespace std;
const int N=50;

struct node{
    int r,l;
}a[N];

int in[N],post[N];

int build(int l1,int l2,int r1,int r2){//中序,后序
    if(l1>l2) return 0;
    int root=post[r2];
    int p=l1;
    while(in[p]!=root) p++;
    int cnt=p-l1;
    a[root].l=build(l1,p-1,r1,r1+cnt-1);
    a[root].r=build(p+1,l2,r1+cnt,r2-1);
    return root;
}

void bfs(int x){
    queue<int> q;
    vector<int> v;
    q.push(x);
    while(!q.empty()){
        int t=q.front();
        q.pop();
        if(t==0) break;
        v.push_back(t);
        if(a[t].l!=0) q.push(a[t].l);
        if(a[t].r!=0) q.push(a[t].r);
     }
    int len=v.size();
    for(int i=0;i<len;i++)
        printf("%d%c",v[i],i==len-1?'\n':' ');
    return;
}


// void bfs(int root){//求前序遍历
//     cout<<root<<" ";
//     if(a[root].l!=0) bfs(a[root].l);
//     if(a[root].r!=0) bfs(a[root].r);
// }

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++) cin>>post[i];
    for(int i=0;i<n;i++) cin>>in[i];
    build(0,n-1,0,n-1);
    int root=post[n-1];
    bfs(root);
}

L2-011 玩转二叉树

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=5000;
struct note{
    int l,r;
}a[N];
int in[N],pre[N];

int build(int l1,int l2,int r1,int r2){//中,前
    if(l1>l2) return 0;
    int p=l1;
    int root=pre[r1];
    while(in[p]!=root) p++;
    int cnt=p-l1;
    a[root].r=build(l1,p-1,r1+1,r1+cnt);
    a[root].l=build(p+1,l2,r1+cnt+1,r2);
    return root;
}
void bfs(int root){
    vector<int> v;
    queue<int> q;
    q.push(root);
    while(q.size()){
        int t=q.front();
        q.pop();
        if(t==0) break;
        v.push_back(t);
        if(a[t].l!=0){
            q.push(a[t].l);
        }
        if(a[t].r!=0){
            q.push(a[t].r);
        }
    }
    for(int i=0;i<v.size();i++){
        if(i) cout<<" "<<v[i];
        else cout<<v[i];
    }
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++) cin>>in[i];
    for(int i=0;i<n;i++) cin>>pre[i];
    build(0,n-1,0,n-1);
    int root=pre[0];
    bfs(root);
    return 0;
}

L2-007 家庭房产

在这里插入图片描述
并查集,多个数组,sz,house,area,p,st

#include<bits/stdc++.h>
using namespace std;
const int N=10100;

struct node{
    int num,id;
    int area,tao;
    bool operator<(const node &b) const
    {
        if (area * b.num != b.area * num)
            return area * b.num > b.area * num;
        return id < b.id;
    }
}a[N];

int p[N],sz[N],house[N],area[N];
int st[N];

void init(){
    for(int i=0;i<N;i++){
    	p[i]=i,
		sz[i]=1;
	}
}

int find(int x){
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

void merge(int a,int b){
	st[a]=st[b]=1;//这个不要忘了标记 
    int pa=find(a),pb=find(b);
    if(pa==pb) return;
    if(pa>pb) swap(pa,pb);
    p[pb]=pa;
    sz[pa]+=sz[pb];
    house[pa]+=house[pb];
    area[pa]+=area[pb];
}

int main(){
    int n;
    cin>>n;
    int child[10];
    init();
    for(int i=0;i<n;i++){
        int id,fa,ma,k,hou,ar;
        cin>>id>>fa>>ma>>k;
        st[id]=1;
        for(int j=0;j<k;j++){
            cin>>child[j];
        }
        cin>>hou>>ar;
        house[find(id)]+=hou,area[find(id)]+=ar;
        if(fa!=-1){
            merge(id,fa);
        }
        if(ma!=-1)
            merge(id,ma);
        for(int j=0;j<k;j++){
            merge(id,child[j]);
        }
    }
    int cnt=0;
    for(int i=0;i<N;i++){
        if(find(i)==i&&st[i]){
            a[cnt].id=i;
            a[cnt].num=sz[i];
            a[cnt].area=area[i];
            a[cnt].tao=house[i];
            cnt++;
        }
    }
    sort(a,a+cnt);
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++){
        printf("%04d %d %.3f %.3f\n",a[i].id,a[i].num,
               a[i].tao/(float)a[i].num,a[i].area/(float)a[i].num);
    }
    return 0;
}

L2-008 最长对称子串

在这里插入图片描述

暴力,枚举长度,起点zhongdian

#include<bits/stdc++.h>
using namespace std;

const int N=1010;

int main(){
    string s;
    getline(cin,s);
    int mx=0;
    for(int len=1;len<=s.size();len++){
        for(int i=0;i+len-1<s.size();i++){
            int j=i+len-1;
            bool flag=false;
            for(int l=i,r=j;r-l>=0;l++,r--){
                if(s[l]!=s[r]){
                    flag=true;
                    break;
                }
            }
            if(!flag) mx=max(mx,len);
        }
    }
    cout<<mx<<endl;
}

dp

#include<bits/stdc++.h>
using namespace std;
const int N=1010;

char a[N];
int dp[N][N];//dp[i][j]表示字符串i到j是对称字符

int main() {
    scanf("%[^\n]",a);
    int n=strlen(a);
    int ans=1;
    for (int i = 0; i < n; i++){
        dp[i][i] = 1;
        if(a[i+1]==a[i]&&i+1<n){
            dp[i][i+1]=1;
            ans=2;
        }
    }
        

    for (int len = 2; len <= n; len++) {
        for (int i = 0; i < n - len + 1; i++) {
            int j = i + len - 1;
            if (a[i] == a[j]&&dp[i+1][j-1]){
                dp[i][j]=1;
                ans=max(ans,len);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

马拉车模型O(n)的复杂度
get_d
scanf("%[^\n],a+1);

马拉车算法——在O(n)的时间内求出一个字符串中的最长回文串
#include<bits/stdc++.h>
using namespace std;
const int N=1e7;

char a[N],s[N];
int d[N];

void get_d(char s[],int n){
    d[1]=1;
    for(int i=2,l,r=1;i<=n;i++){
        if(i<=r) d[i]=min(d[r-i+l],r-i+1);
        while(s[i-d[i]]==s[i+d[i]]) d[i]++;
        if(i+d[i]-1>r) l=i-d[i]+1,r=i+d[i]-1;
    }
}

int main(){
    scanf("%[^\n]",a+1);
    int n=strlen(a+1),k=0;
    s[0]='$',s[++k]='#';
    for(int i=1;i<=n;i++)
        s[++k]=a[i],s[++k]='#';
    
    n=k;
    get_d(s,n);
    int mx=0;
    for(int i=1;i<=n;i++){
        // cout<<d[i]<<endl;
        mx=max(mx,d[i]-1);
    }
    cout<<mx<<endl;
    return 0;
}

L2-009 抢红包

在这里插入图片描述
结构体排序

#include<bits/stdc++.h>
using namespace std;
const int N=10100;

struct note{
    int num,cnt;
    double mon;
    bool operator<(const note& w) const{
        // if(mon!=w.mon) return mon>w.mon;
        // else{
        //     if(cnt!=w.cnt) return cnt>w.cnt;
        //     else return num<w.num;
        // }
            if(mon!=w.mon) return mon>w.mon;
            else if(cnt!=w.cnt) return cnt>w.cnt;
            else return num<w.num;
    }
}a[N];

int main(){
    int n,k;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>k;
        a[i].num=i;
        for(int j=0;j<k;j++){
            int t1,t2;
            cin>>t1>>t2;
            a[t1].mon+=t2;
            a[t1].cnt++;
            a[i].mon-=t2;
        }
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){
        printf("%d %.2lf\n",a[i].num,a[i].mon/100);
    }
    return 0;
}

L2-010 排座位

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=110;
int p[N];
int g[N][N];
int find(int x){
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}
void unique(int a,int b){
    int pa=find(a),pb=find(b);
    if(pa!=pb){
        p[pa]=pb;
    }
}
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<N;i++) p[i]=i;
    while(m--){
        int a,b,c;
        cin>>a>>b>>c;
        if(c==-1){
            g[a][b]=g[b][a]=1;
        }else{
            unique(a,b);
        }
    }
    while(k--){
        int a,b;
        cin>>a>>b;
        int pa=find(a),pb=find(b);
        if(g[a][b]){
            if(pa==pb){
                cout<<"OK but..."<<endl;
            }else cout<<"No way"<<endl;
        }else{
            if(pa==pb) cout<<"No problem"<<endl;
            else cout<<"OK"<<endl;
        }
    }
    return 0;
}

L2-012 关于堆的判断

在这里插入图片描述
make_heap建堆

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
// priority_queue<int,vector<int>,greater<int> > h;
map<int,int> mp;
int n,m;
vector<int> hp(0,0);

int main(){
    cin>>n>>m;
    int x;
    for(int i=1;i<=n;i++){
        cin>>x;
        hp.push_back(x);
        make_heap(hp.begin(),hp.end(),greater<int>());
    }
    for(int i=0;i<n;i++){
        // mp.insert({hp[i],i+1});
        mp[hp[i]]=i+1;
    }
    while(m--){
        int a,b;
        string s;
        cin>>a>>s;
        if(s[0]=='a'){
            cin>>b>>s>>s;
            cout<<(mp[a]/2==mp[b]/2?"T":"F")<<endl;
            // cout<<(abs(mp[a]-mp[b])==1?"T":"F")<<endl;//不能用这个判断,因为两个相邻的数都可以,例如5,6
        }else{
            cin>>s>>s;
            if(s[0]=='r'){
                if(mp[a]==1) cout<<"T"<<endl;
                else cout<<"F"<<endl;
            }else if(s[0]=='p'){
                cin>>s>>b;
                cout<<(mp[a]==mp[b]/2?"T":"F")<<endl;
            }else{
                cin>>s>>b;
                cout<<(mp[a]/2==mp[b]?"T":"F")<<endl;
            }
        }
    }
    return 0;
}

L2-013 红色警报

在这里插入图片描述
多次遍历求连通块的个数

#include<bits/stdc++.h>
using namespace std;
const int N=5050;

int n,m,k,last_cnt,cnt,u;
int g[N][N];
bool st[N];
void dfs(int u){
    st[u]=true;
    for(int i=0;i<n;i++){
        if(g[u][i]&&!st[i])
            dfs(i);
    }
}

int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        g[a][b]=g[b][a]=1;
    }
    for(int i=0;i<n;i++){
        if(!st[i]){
            dfs(i);
            ++last_cnt;
        }
    }
    cin>>k;
    int flag=n;
    while(k--){
        cin>>u;
        flag--;
        for(int i=0;i<n;i++){
            g[u][i]=g[i][u]=0;
        }
        memset(st,0,sizeof st);
        cnt=0;
        for(int i=0;i<n;i++){
            if(!st[i])
                dfs(i),++cnt;
        }
        if(last_cnt+1<cnt) 
            printf("Red Alert: City %d is lost!\n",u);
        else
            printf("City %d is lost.\n",u);
        last_cnt=cnt;
    }
    if(!flag) printf("Game Over.\n");
    return 0;
}

L2-014 列车调度

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    set<int> s;
    cin>>n;
    s.insert(1e5+5);
    while(n--){
        int x;
        cin>>x;
        if(x<*s.rbegin()){
            s.erase(*s.upper_bound(x));
        }
        s.insert(x);
    }
    cout<<s.size();
    return 0;
}

L2-015 互评成绩

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;

int main(){
    int n,m,k,x;
    vector<int> v;
    cin>>n>>m>>k;
    for(int i=0;i<n;i++){
        int mx=-5,mn=105,cnt=0;
        for(int j=0;j<m;j++){
            cin>>x;
            mx=max(mx,x),mn=min(mn,x);
            cnt+=x;
        }
        // cout<<cnt<<endl;
        v.push_back(cnt-mx-mn);
    }
    // cout<<endl;
    sort(v.begin(),v.end(),greater<int>());
    // for(auto itm:v) cout<<itm<<endl;
    // cout<<endl<<m<<endl;
    for(int i=k-1;i>=0;i--){
        if(i) printf("%.3lf ",1.0*v[i]/(m-2));
        else printf("%.3lf",1.0*v[i]/(m-2));//除要记得括号
    }
    return 0;
}

L2-016 愿天下有情人都是失散多年的兄妹

在这里插入图片描述

bfs将两个待查询的人的五代放进set进行判重

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N=1e6+10;//段错误说明指针越界了,数组开小了1e4+10不行
char sex[N];
vector<int> v[N];//v(N)表示一维数组,v[N]表示二维数组

bool bfs(int a,set<int> &s){
    queue<pii> q;
    q.push({a,1});
    while(q.size()){
        auto t=q.front();
        q.pop();
        int x=t.first,h=t.second;
        if(s.count(x)) return false;
        s.insert(x);
        for(int i=0;i<v[x].size();i++)
            if(h<5)
                q.push({v[x][i],h+1});
    }
    return true;
}

int main(){
    int n,k;
    cin>>n;
    int id,fa,ma;
    char se[2];
    while(n--){
        cin>>id>>se>>fa>>ma;
        sex[id]=se[0];
        if(fa!=-1){
            v[id].push_back(fa);
            sex[fa]='M';//双亲性别记得标记,不然有测试点过不去
        }
        if(ma!=-1){
            v[id].push_back(ma);
            sex[ma]='F';
        }
    }
    cin>>k;
    while(k--){
        int a,b;
        cin>>a>>b;
        // cout<<sex[a]<<" "<<sex[b]<<endl;
        if(sex[a]==sex[b]) cout<<"Never Mind"<<endl;
        else{
            set<int> st;
            st.clear();
            bfs(a,st);
            if(bfs(b,st)) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }
    }
    return 0;
}

L2-017 人以群分

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
long long cnt1,cnt2;

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++){
        if(i<n/2) cnt1+=a[i];
        else cnt2+=a[i];
    }
    long long ans=cnt2-cnt1;
    if(n%2){
        printf("Outgoing #: %d\n",n/2+1);
        printf("Introverted #: %d\n",n/2);
        printf("Diff = %lld",ans);
    }else{
        printf("Outgoing #: %d\n",n/2);
        printf("Introverted #: %d\n",n/2);
        printf("Diff = %lld",ans);
    }
}

L2-018 多项式A除以B

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=100000;
double a[N],b[N],c[N];
int ma,mb;

int sc(double t[],int start){
    int cnt=0;
    for(int i=start;i>=0;i--)
        if(fabs(t[i])>0.05) cnt++;
    return cnt;
}

void print(double t[],int start){
    printf("%d",sc(t,start));
    if(sc(t,start)==0) printf(" 0 0.0");
    else{
        for(int i=start;i>=0;i--){
            if(fabs(t[i])>0.05)
                printf(" %d %.1lf",i,t[i]);
        }
    }
}

int main(){
    int n,m;
    cin>>n;
    int k;
    for(int i=0;i<n;i++){
        cin>>k;
        cin>>a[k];
        ma=max(ma,k);
    }
    cin>>m;
    for(int i=0;i<m;i++){
        cin>>k;
        cin>>b[k];
        mb=max(mb,k);
    }
    int t1=ma,t2=mb;
    while(ma>=mb){
        double t=a[ma]/b[mb];
        c[ma-mb]=t;
        for(int i=ma,j=mb;j>=0;j--,i--) a[i]-=b[j]*t;
        while(fabs(a[ma])<0.00001) ma--;
    }
    print(c,t1-t2);
    printf("\n");
    print(a,ma);
    return 0;
}

L2-019 悄悄关注

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
int main(){
    int n,m;
    cin>>n;
    string s;
    double x,sum=0;
    set<string> se;
    map<string,double> mp;
    while(n--){
        cin>>s;
        se.insert(s);
    }
    cin>>m;
    n=m;
    while(m--){
        cin>>s>>x;
        mp[s]=x;
        sum+=x;
    }
    double avg=sum*1.0/n;
    bool f=false;
    for(auto it:mp){
        if(it.y>avg&&!se.count(it.x)){
            cout<<it.x<<endl;
            f=true;
        }
    }
    if(!f) cout<<"Bing Mei You";
    return 0;
}

L2-020 功夫传人

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> a[N];

int d[N];//d[i]为编号为i得道者的放大倍数
int n;
double z,r,ans;

void dfs(int u,int cnt){//cnt表示当前为第cnt代
    if(!a[u].size()){
        ans+=d[u]*z*pow(r,cnt);
    }
    for(int i=0;i<a[u].size();i++){
        dfs(a[u][i],cnt+1);
    }
}

int main(){
    cin>>n>>z>>r;
    r=(100-r)/100;
    for(int i=0;i<n;i++){
        int k;
        cin>>k;
        if(!k) cin>>d[i];
        for(int j=0;j<k;j++){
            int x;
            cin>>x;
            a[i].push_back(x);
        }
    }
    dfs(0,0);
    printf("%d\n",(int)ans);//取整数技巧
    return 0;
}

L2-021 点赞狂魔021

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1000;
struct note{
    string name;
    int cnt;
    double avg;
    bool operator<(const note& w) const{
        if(cnt!=w.cnt) return cnt>w.cnt;
        return avg>w.avg;
    }
}a[N];
int main(){
    int n,k;
    cin>>n;
    string s;
    for(int i=0;i<n;i++){
        cin>>s>>k;
        set<int> st;
        int cnt=0;
        for(int j=0;j<k;j++){
            int x;
            cin>>x;
            if(st.count(x)) continue;
            st.insert(x);
            cnt++;
        }
        a[i].name=s,a[i].cnt=cnt,a[i].avg=1.0*cnt/k;
    }
    sort(a,a+n);
    // for(int i=0;i<n;i++){
    //     cout<<a[i].name<<" "<<a[i].cnt<<" "<<a[i].avg<<endl;
    // }
    
    if(n>=3){
        for(int i=0;i<3;i++)
            if(i) cout<<" "<<a[i].name;
            else cout<<a[i].name;
    }else if(n==2){
        cout<<a[0].name<<" "<<a[1].name<<" "<<"-";
    }else if(n==1){
        cout<<a[0].name<<" "<<"-"<<" "<<"-";
    }else
        cout<<"-"<<" "<<"-"<<" "<<"-";
    return 0;
}

L2-022 重排链表

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+10;
struct note{
    string add,next;
    int data;
}a[N],q;
string head;
map<string,pair<int,string>> mp;
int n;

int main(){
    cin>>head>>n;
    for(int i=0;i<n;i++){
        string add,next;
        int data;
        cin>>add>>data>>next;
        mp[add]={data,next};
    }
    //将答案下标转移到0~cnt-1
    int cnt=0;
    while(head!="-1"){
        a[cnt].add=head;
        a[cnt++].data=mp[head].first;
        head=mp[head].second;
    }
    for(int l=0,r=cnt-1;l<=r;l++,r--){
        if(l!=r){
            cout<<a[r].add<<" "<<a[r].data<<" "<<a[l].add<<endl;
            cout<<a[l].add<<" "<<a[l].data<<" "<<((l+1==r)?"-1":a[r-1].add)<<endl;
        }
        else
            cout<<a[l].add<<" "<<a[l].data<<" "<<"-1"<<endl;
    }
    return 0;
}

L2-023 图着色问题

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=550;
vector<int> g[N];
bool st[N];
int color[N];
int v,e,k,n;

bool dfs(int u){
    st[u]=true;
    // for(int i=0;i<g[u].size();i++){//上面注意对应的点是g[u][i]
    //     if(color[u]==color[g[u][i]]) return false;
    //     if(st[g[u][i]]) continue;
    //     if(!dfs(g[u][i])) return false;
    // }
    for(auto i:g[u]){
        if(color[u]==color[i]) return false;
        if(st[i]) continue;
        if(!dfs(i)) return false;
    }
    return true;
}
int main(){
    cin>>v>>e>>k;
    while(e--){
        int a,b;
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    cin>>n;
    while(n--){
        set<int> s;
        for(int i=1;i<=v;i++){
            cin>>color[i];
            s.insert(color[i]);
        }
        if(s.size()!=k){
            cout<<"No"<<endl;
            continue;
        }
        memset(st,false,sizeof st);
        bool flag=false;
        for(int i=1;i<=v;i++){
            if(!st[i]){
                if(!dfs(i)){
                    cout<<"No"<<endl;
                    flag=true;
                    break;
                }
            }
        }
        if(!flag) cout<<"Yes"<<endl;
    }
    return 0;
}

L2-024 部落

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;

int p[N];
int n,k;
bool st[N];

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 unite(int a,int b){
    int pa=find(a),pb=find(b);
    if(pa!=pb){
        p[pa]=pb;
    }
}
int main(){
    init();
    cin>>n;
    set<int> se;
    int x;
    while(n--){
        cin>>k;
        int t;
        cin>>t;
        se.insert(t);
        st[t]=true;
        for(int i=1;i<k;i++){
            cin>>x;
            se.insert(x);
            unite(x,t);
            st[x]=true;
        }
    }
    int cnt=0;
    // for(int i=1;i<N;i++){
    //     if(st[i]&&p[i]==i)
    //         cnt++;
    // }
    for(auto i:se){
        if(p[i]==i)
            cnt++;
    }
    cout<<se.size()<<" "<<cnt<<endl;
    int q;
    cin>>q;
    while(q--){
        int a,b;
        cin>>a>>b;
        if(find(a)==find(b)) cout<<"Y"<<endl;
        else cout<<"N"<<endl;
    }
    return 0;
}

L2-025 分而治之

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int n,m,k;
struct note{
    int a,b;
}e[N];
bool st[N];

int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        e[i]={a,b};
    }
    cin>>k;
    while(k--){
        int np;
        cin>>np;
        int x;
        memset(st,false,sizeof st);
        for(int i=0;i<np;i++){
            cin>>x;
            st[x]=true;
        }
        bool flag=false;
        for(int i=0;i<m;i++){
            int a=e[i].a,b=e[i].b;
            if(!st[a]&&!st[b]){
                cout<<"NO"<<endl;
                flag=true;
                break;
            }
        }
        if(!flag) cout<<"YES"<<endl;
    }
    return 0;
}

L2-026 小字辈

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> v[N],h[N];
int mx=0;

void bfs(int root,int hg){
    queue<pair<int,int>> q;
    q.push({root,hg});
    while(!q.empty()){
        auto t=q.front();
        q.pop();
        int x=t.first,hi=t.second;
        h[hi].push_back(x);
        mx=max(mx,hi);
        for(auto it:v[x]){
            q.push({it,hi+1});
        }
    }
}
int main(){
    int n,root;
    cin>>n;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        if(x==-1) root=i;
        else{
            v[x].push_back(i);
        }
    }
    bfs(root,1);
    cout<<mx<<endl;
    for(int i=0;i<h[mx].size();i++){
        if(i) cout<<" "<<h[mx][i];
        else cout<<h[mx][i];
    }
    return 0;
}

L2-027 名人堂与代金券

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;

struct node{
    string name;
    int num;
    bool operator<(const node& w) const{
        if(num!=w.num) return num>w.num;
        else return name<w.name;
    }
}a[N];

int main(){
    int n,g,k;
    cin>>n>>g>>k;
    int sum=0;
    for(int i=0;i<n;i++){
        string name;
        int num;
        cin>>name>>num;
        if(num>=g) sum+=50;
        else if(num<g&&num>=60) sum+=20;
        a[i]={name,num};
    }
    cout<<sum<<endl;
    sort(a,a+n);
    // for(int i=0;i<n;i++){
    //     cout<<a[i].name<<" "<<a[i].num<<endl;
    // }
    
    int cnt=1;
    for(int i=0;i<n;i++){
        cout<<cnt<<" "<<a[i].name<<" "<<a[i].num<<endl;
        int j=i+1;
        while(a[i].num==a[j].num){
            cout<<cnt<<" "<<a[j].name<<" "<<a[j].num<<endl;
            j++;
        }
        int len=j-i;
        cnt+=len;
        i=j-1;//这个不要忘了
        if(cnt>k) break;
    }
    return 0;
}

L2-028 秀恩爱分得快

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1100;

double g[N][N];
double mx_a,mx_b;//要用double类型,用int类型寄,mx_a表示a新密度最高的异性值
int ph[N],sex[N];
vector<int> ans_a,ans_b;

int main(){
    // memset(sex,-1,sizeof sex);
    // fill(sex,sex+N,-1);
    int n,m,k;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>k;
        string s;
        for(int j=0;j<k;j++){
            cin>>s;
            int t=fabs(stoi(s));
            if(s[0]=='-') sex[t]=1;//女性
            else sex[t]=0;
            ph[j]=t;
        }
        for(int j=0;j<k;j++){
            for(int z=j+1;z<k;z++){
                if(sex[ph[j]]^sex[ph[z]])
                    g[ph[j]][ph[z]]=g[ph[z]][ph[j]]+=1.0/k;
            }
        }
    }
    string a,b;
    cin>>a>>b;
    int na=fabs(stoi(a)),nb=fabs(stoi(b));
    for(int i=0;i<n;i++){
        if(g[na][i]>mx_a&&sex[na]^sex[i]){
            mx_a=g[na][i];
            ans_a.clear();
            ans_a.push_back(i);
        }else if(g[na][i]==mx_a&&sex[na]^sex[i]){
            ans_a.push_back(i);
        }

        if(g[nb][i]>mx_b&&sex[nb]^sex[i]){
            mx_b=g[nb][i];
            ans_b.clear();
            ans_b.push_back(i);
        }else if(g[nb][i]==mx_b&&sex[nb]^sex[i]){
            ans_b.push_back(i);
        }
        
    }
    if(g[na][nb]==mx_a&&g[na][nb]==mx_b){
        cout<<a<<" "<<b;
    }else{
        // cout<<"hhh"<<endl;
        for(auto x:ans_a){
            cout<<a<<" ";
            if(sex[x]==1) cout<<'-';
            cout<<x<<endl;
        }
        for(auto x:ans_b){
            cout<<b<<" ";
            if(sex[x]==1) cout<<'-';
            cout<<x<<endl;
        }
    }
    return 0;
}

L2-029 特立独行的幸福

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int num[N],st[N];//不是独立的幸福数标记一下

bool isprime(int x){
    if(x<2) return false;
    for(int i=2;i<=x/i;i++){
        if(x%i==0)
            return false;
    }
    return true;
}

bool check(int x){
    set<int> se;
    int t=x;
    while(t!=1){
        se.insert(t);
        int t1=t,t2=0;
        while(t1){
            int v=t1%10;
            t2+=v*v;
            t1=t1/10;
        }
        num[x]++;
        t=t2;
        st[t2]=1;
        if(se.count(t2)) return false;
    }
    return true;
}

int main(){
    int a,b;
    vector<int> ans;
    cin>>a>>b;
    for(int i=a;i<=b;i++){
        if(check(i)) ans.push_back(i);
    }
    // for(auto i:ans){
    //     cout<<i<<" "<<num[i]<<endl;
    // }
    bool flag=false;
    for(auto i:ans){
        int res=num[i];
        if(isprime(i))  res=num[i]*2;
        if(!st[i]){
            cout<<i<<" "<<res<<endl;
            flag=true;
        }
    }
    if(!flag) cout<<"SAD"<<endl;
    return 0;
}

L2-030 冰岛人

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef pair<int,string> pis;
string m,x,temp;
map<string,pis> r;

string check(string a,string b){
    int cnt1=0,cnt2;
    while(a!=""){
        cnt2=0;
        string b1=b;
        while(b1!=""){
            if(a==b1&&(cnt1<4||cnt2<4)) return "No\n";
            if(cnt1>=4&&cnt2>=4) return "Yes\n";
            b1=r[b1].second;
            cnt2++;
        }
        cnt1++;
        a=r[a].second;
    }
    return "Yes\n";
}

//答案错误3,6。两个人有共同祖先,是一个人的三代,另一个人的六代,也不行
// string check(string a,string b){
//     set<string> s;
//     int cnt=0;
//     while(a!=""){
//         s.insert(a);
//         cnt++;
//         a=r[a].second;
//         if(cnt>=4) break;
//     }
//     cnt=0;
//     while(b!=""){
//         if(s.count(b)) return "No\n";
//         s.insert(b);
//         b=r[b].second;
//         cnt++;
//         if(cnt>=4) break;
//     }
//     return "Yes\n";
// }


int main(){
    int n;
    cin>>n;
    while(n--){
        cin>>m>>x;
        if(x.back()=='n') r[m]={1,x.substr(0,x.size()-4)};//男标记1
        else if(x.back()=='r') r[m]={0,x.substr(0,x.size()-7)};
        else if(x.back()=='m') r[m].first=1;
        else r[m].first=0;
    }
    int q;
    cin>>q;
    while(q--){
        cin>>m>>temp>>x>>temp;
        if(!r.count(m)||!r.count(x)) cout<<"NA\n";
        else if(r[m].first==r[x].first) cout<<"Whatever\n";
        else cout<<check(m,x);
    }
    return 0;
}

L2-031 深入虎穴

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
vector<int> v[N];
queue<int> q;
int st[N];

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int k,x;cin>>k;
        for(int j=0;j<k;j++){
            cin>>x;
            v[i].push_back(x);
            v[x].push_back(i);//双向边,不要忘了
        }
    }
    q.push(1);
    st[1]=1;
    int t;
    while(q.size()){
        t=q.front();
        q.pop();
        for(auto i:v[t]){
            if(st[i]) continue;
            st[i]=1;//注意标记,不然会内存超限
            q.push(i);
        }
    }
    cout<<t<<endl;
    return 0;
}

L2-032 彩虹瓶

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,m,k,x;
    cin>>n>>m>>k;
    for(int i=0;i<k;i++){
        stack<int> sk;
        int cnt=1;
        // bool flag=false;
        // for(int j=0;j<n;j++){
        //     cin>>x;
        //     if(x==cnt){
        //         cnt++;
        //         while(sk.size()&&sk.top()==cnt){
        //             cnt++;
        //             sk.pop();
        //         }
        //     }else{
        //         sk.push(x);//要放前面不然会错误
        //         if(sk.size()>m){
        //             flag=true;
        //         }
        //     }
        // }
        // if(!sk.size()&&!flag) cout<<"YES\n";
        // else cout<<"NO\n";

        for(int j=0;j<n;j++){
            cin>>x;
            if(x==cnt){
                cnt++;
                while(sk.size()&&sk.top()==cnt){
                    cnt++;
                    sk.pop();
                }
            }else if(sk.size()<m) sk.push(x);
        }
        if(!sk.size()) cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}

L2-033 简单计算器

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1050;
stack<int> s1;
stack<char> s2;

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int x;cin>>x;
        s1.push(x);
    }
    for(int i=0;i<n-1;i++){
        char a[2];cin>>a;
        s2.push(a[0]);
    }
    while(s2.size()&&s1.size()){
        int n1=s1.top();s1.pop();
        int n2=s1.top();s1.pop();
        char op=s2.top();s2.pop();
        if(op=='/'&&n1==0){
            cout<<"ERROR: "<<n2<<'/'<<n1<<endl;
            return 0;
        }
        int ans;
        if(op=='+') ans=n1+n2,s1.push(ans);
        else if(op=='-') ans=n2-n1,s1.push(ans);
        else if(op=='*') ans=n1*n2,s1.push(ans);
        else if(op=='/') ans=n2/n1,s1.push(ans);
    }
    cout<<s1.top()<<endl;
    return 0;
}

L2-034 口罩发放

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=3e4+10;

struct note{
    string name,code;
    int h;
    int hh,mm;
    int num;
}a[N];
bool cmp(note a,note b){
    if(a.hh!=b.hh) return a.hh<b.hh;
    else if(a.mm!=b.mm) return a.mm<b.mm;
    else return a.num<b.num;
}
set<pair<string,string>> se;//unordered_set不能用pair元素
map<string,int> mp;
vector<pair<string,string>> ans;

bool check(string s){
    if(s.size()!=18) return false;
    for(int i=0;i<s.size();i++)
        if(!isdigit(s[i]))
            return false;
    return true;
}
int main(){
    int d,p,s,t;
    string name,code;
    int h,hh,mm;
    cin>>d>>p;
    for(int k=0;k<d;k++){
        cin>>t>>s;
        int cnt=0;
        for(int i=0;i<t;i++){
            cin>>name>>code>>h;
            scanf("%d:%d",&hh,&mm);
            if(check(code)){
                a[cnt]={name,code,h,hh,mm,cnt};//又是cnt这里栽了一下
                if(h==1) 
                    ans.push_back({name,code});
                    // se.insert({name,code});
                //对于code合格并且健康状况不好的要先存起来,
                //不能用se判重,因为set会自动按字母顺序排序,而输出要求是谁先出现谁先输出
                cnt++;
            }
        }
        sort(a,a+cnt,cmp);
        for(int i=0;i<cnt;i++){
            if(s&&(!mp.count(a[i].code)||(k-mp[a[i].code])>=p+1)){
                cout<<a[i].name<<" "<<a[i].code<<endl;
                s--;
                mp[a[i].code]=k;//要放里面,拿了口罩才标记
            }
        }
        
    }
    
    for(auto it:ans){
        if(se.count(it)) continue;
        se.insert(it);
        cout<<it.first<<" "<<it.second<<endl;
    }

    // for(auto it:se){
    //     cout<<it.first<<" "<<it.second<<endl;
    // }
    return 0;
}

L2-035 完全二叉树的层序遍历

在这里插入图片描述
根据下标输入

#include<bits/stdc++.h>
using namespace std;
const int N=40;

int a[N];
int n;

void build(int x){
    if(x>n) return;
    build(x<<1),build((x<<1)+1);
    cin>>a[x];
}
int main(){
    cin>>n;
    build(1);
    for(int i=1;i<=n;i++)
        cout<<(i==1?"":" ")<<a[i];
    return 0;
}

L2-036 网红点打卡攻略

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=210;
int d[N][N];
int path[N];

int main(){
    int n,m,k;
    cin>>n>>m;
    while(m--){
        int a,b,t;
        cin>>a>>b>>t;
        d[a][b]=d[b][a]=t;
    }
    cin>>k;
    int cnt=0,number,ans=1e9+10;
    for(int z=1;z<=k;z++){
        int num;
        cin>>num;
        set<int> se;
        fill(path,path+N,0);//记得初始化,不然不能用path[0],path[num+1]是0
        for(int i=1;i<=num;i++){
            cin>>path[i];
            se.insert(path[i]);
        }
        if(num!=n||se.size()!=n) continue;
        bool flag=false;
        int sum=0;
        for(int i=1;i<=num+1;i++){
            if(d[path[i-1]][path[i]]==0){
                flag=true;
                break;
            }
            sum+=d[path[i-1]][path[i]];
        }
        if(flag) continue;
        cnt++;
        if(sum<ans){
            number=z;
            ans=sum;
        }
    }
    cout<<cnt<<endl<<number<<" "<<ans<<endl;
    return 0;
}

L2-037 包装机

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
queue<char> q[N];
vector<char> v;
stack<char> sk;

int main(){
    int n,m,s;
    cin>>n>>m>>s;
    for(int i=1;i<=n;i++){
        string t;
        cin>>t;
        for(int j=0;j<t.size();j++)
            q[i].push(t[j]);
    }
    int t;
    while(cin>>t){
        if(t==-1) break;
        if(t==0){
            if(sk.size()){
                v.push_back(sk.top());
                sk.pop();
            }
        }else{
            if(q[t].size()==0) continue;//当上面队列个数为零,不推,零操作,最后一个测试点
            if(sk.size()==s){
                v.push_back(sk.top());
                sk.pop();
            }
            if(q[t].size()){
                sk.push(q[t].front());
                q[t].pop();
            }
        }
    }
    for(int i=0;i<v.size();i++)
        cout<<v[i];
    return 0;
}

L2-038 病毒溯源

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
vector<int> v[N],ans;
int in[N],pa[N];
queue<pair<int,int>> q;
int len;

int main(){
    int n,k,x,res;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>k;
        for(int j=0;j<k;j++){
            cin>>x;
            v[i].push_back(x);
            pa[x]=i;
            in[x]++;
        }
        sort(v[i].begin(),v[i].end());
    }
    //找源头方法 1.遍历每个点dfs. 2.标记入度,入度为零即源头
    int root;
    for(int i=0;i<n;i++) if(in[i]==0) root=i;
    q.push({root,1});
    while(q.size()){
        auto t=q.front();
        q.pop();//记得弹出,不然内存超限
        int s=t.first,h=t.second;
        if(len<h){
            len=h;//最长长度
            res=s;//最后一个病毒变异株
        }
        for(auto it:v[s]){
            q.push({it,h+1});
        }
    }
    cout<<len<<endl;
    while(res!=root){
        ans.push_back(res);
        res=pa[res];
    }
    ans.push_back(res);
    for(int i=ans.size()-1;i>=0;i--)
        cout<<ans[i]<<(i==0?"\n":" ");
    return 0;
}

L2-039 清点代码库

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
vector<int> temp;
map<vector<int>,int> a;
multimap<int,vector<int>,greater<int> > b;

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        temp.clear();
        for(int j=0;j<m;j++){
            int x;
            cin>>x;
            temp.push_back(x);
        }
        a[temp]++;
    }
    cout<<a.size()<<endl;
    for(auto it:a) 
		b.insert({it.second,it.first});
//		b[it.second]=it.first;//不能用这个,因为multimap容器可以key重复,value不同 
    for(auto it:b){
        cout<<it.first;
        for(auto it2:it.second) cout<<" "<<it2;
        cout<<endl;
    }
    return 0;
}

L2-040 哲哲打游戏

在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
    int pos;
    vector<int> path;
};
int n,m,k,now=1,x;
vector<int> temp,e[N];
vector<node> save(105);

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>k;
        for(int j=0;j<k;j++){
            cin>>x;
            e[i].push_back(x);
        }
    }
    temp.push_back(1);//起始剧情记得加入
    while(m--){
        int op;
        cin>>op>>x;
        if(op==0){
            temp.push_back(e[now][x-1]);
            now=e[now][x-1];
        }else if(op==1){
            save[x].pos=now;
            save[x].path=temp;
            cout<<now<<endl;
        }else{
            now=save[x].pos;
            temp=save[x].path;
        }
    }
    cout<<temp.back();
    return 0;
}

L2-041 插松枝

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,k,x,last=INT_MAX;
queue<int> q;//deque
stack<int> sk;
vector<int> ans;

void outprint(){
    for(int i=0;i<ans.size();i++)
        cout<<(i==0?"":" ")<<ans[i];
    cout<<endl;
    ans.clear();
    last=INT_MAX;//容易忘初始化
}
int main(){
    cin>>n>>m>>k;
    for(int i=0;i<n;i++){
        cin>>x;
        q.push(x);
    }
    while(q.size()||sk.size()){
        if(sk.size()&&sk.top()<=last){
            ans.push_back(sk.top());
            last=sk.top();
            sk.pop();
            if(ans.size()==k) outprint();
        }else{
            if(!q.size()) outprint();
            else{
                int t=q.front();
                if(t<=last){
                    ans.push_back(t);
                    last=t;
                    q.pop();
                    if(ans.size()==k) outprint();
                }else{
                    if(sk.size()<m){
                        sk.push(t);
                        q.pop();
                    }else{
                        outprint();
                    }
                }
            }
            
        }
    }
    if(ans.size()) outprint();
    return 0;
}

L2-042 老板的作息表

在这里插入图片描述

#include <iostream>
#include <set>
using namespace std;
set<pair<string, string> > record;
string work_start_time, work_end_time, last_start = "00:00:00";
int main() {
    cin >> work_start_time;
    while (cin >> work_start_time >> work_end_time >> work_end_time) record.insert({work_start_time, work_end_time});
    record.insert({"23:59:59", ""});
    for (auto ite : record) {
        if (last_start < ite.first) cout << last_start << " - " << ite.first << '\n';
        last_start = ite.second;
    }
    return 0;
}

L2-043 龙龙送外卖

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int sum,mx;
int p[N],d[N];//存放父节点,d存放到根节点的距离

int dfs(int u){//返回到根节点的距离
    if(p[u]==-1||d[u]>0) return d[u];
    sum++;
    d[u]=dfs(p[u])+1;
    return d[u];
}

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>p[i];
    while(m--){
        int x;
        cin>>x;
        mx=max(mx,dfs(x));
        cout<<sum*2-mx<<endl;
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
typedef pair<int,int> pii;
vector<int> child[N];
int parent[N],d[N],st[N],n,m,sum,mx;
queue<pii> q;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int pn;
        cin>>pn;
        if(pn<0) parent[0]=i;//外买站为i
        else child[pn].push_back(i);
        parent[i]=pn;
    }
    st[parent[0]]=1;
    q.push({parent[0],0});
    while(!q.empty()){
        int id=q.front().first,deep=q.front().second;
        q.pop();
        d[id]=deep;
        for(auto ite:child[id]) q.push({ite,deep+1});
    }
    for(int i=0;i<m;i++){
        int newadd;
        cin>>newadd;
        int passadd=newadd;
        while(!st[passadd]){
            st[passadd]=1;
            passadd=parent[passadd];
        }
        sum+=d[newadd]-d[passadd];
        mx=max(mx,d[newadd]);
        cout<<sum*2-mx<<endl;
    }
    return 0;
}

L2-044 大众情人

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=505,inf=0x3f3f3f3f;
int d[N][N];
char sex[N];

int main(){
    int n;scanf("%d",&n);
    memset(d,0x3f,sizeof d);
    for(int i=0;i<=n;i++) d[i][i]=0;

    for(int i=1;i<=n;i++){
        char s[2];
        int cnt;
        scanf("%s%d",s,&cnt);
        sex[i]=s[0];
        while(cnt--){
            int id,dist;
            scanf("%d:%d",&id,&dist);
            d[i][id]=dist;
        }
    }

    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]);

    for(auto c:string("FM")){
        int mn=inf;
        for(int i=1;i<=n;i++){
            if(sex[i]==c){
                int mx=0;
                for(int j=1;j<=n;j++)
                    if(sex[j]!=sex[i])
                        mx=max(mx,d[j][i]);
                mn=min(mn,mx);
            }
        }
        bool f=false;
        for(int i=1;i<=n;i++){
            if(sex[i]==c){
                int mx=0;
                for(int j=1;j<=n;j++)
                    if(sex[j]!=sex[i])
                        mx=max(mx,d[j][i]);
                if(mx==mn){
                    if(!f){
                        printf("%d",i);
                        f=true;
                    }else
                        printf(" %d",i);
                }
            }
        }
        puts("");
    }
    return 0;
}

L2-045 堆宝塔

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
stack<int> a,b;
int ans=0,len=0;

void outp(stack<int> &s){
    int cnt=0;
    while(s.size()){
        s.pop();
        cnt++;
    }
    len=max(cnt,len);
}
int main(){
    int n,x;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>x;
        if(a.size()==0||x<a.top()){
            a.push(x);
        }else{
            if(b.size()==0||b.top()<x){
                b.push(x);
            }else{
                ans++;
                outp(a);
                while(b.size()&&b.top()>x){
                    a.push(b.top());
                    b.pop();
                }
                a.push(x);
            }
        }
    }
    if(a.size()) outp(a),ans++;
    if(b.size()) outp(b),ans++;
    cout<<ans<<" "<<len;
    return 0;
}

L2-046 天梯赛的赛场安排

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+10;
int a[N],cnt;
priority_queue<int> q;//heap

int main(){
    int n,c;
    cin>>n>>c;
    for(int i=0;i<n;i++){
        string name;
        int num;
        cin>>name>>num;
        cout<<name<<" "<<ceil(1.0*num/c)<<endl;
        cnt+=num/c;
        if(num%c) q.push(num%c);
    }
    int count=0;
    while(!q.empty()){
        auto t=q.top();
        q.pop();
        bool flag=false;
        for(int i=0;i<count;i++){
            if(a[i]+t<=c){
                a[i]+=t;
                flag=true;
                break;//不要忘了这个,不然后面满足条件的a[i]都会被改变
            }
        }
        if(!flag){
            a[count++]=t;
        }
    }
    cout<<cnt+count;
    return 0;
}

L2-047 锦标赛

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int ans[1<<18],lost[19][1<<18],win[19][1<<18];

int main(){
    int k,w;
    cin>>k;
    for(int i=1;i<=k;i++){
        for(int j=0;j<(1<<(k-i));j++){
            cin>>lost[i][j];
            if(i==1){
                ans[j<<1]=lost[i][j];
                win[i][j]=j<<1|1;
            }else{
                if(lost[i][j]<lost[i-1][j<<1]&&lost[i][j]<lost[i-1][j<<1|1]){
                    cout<<"No Solution\n";
                    return 0;
                }else if(lost[i][j]>=lost[i-1][j<<1]){
                    ans[win[i-1][j<<1]]=lost[i][j];
                    win[i][j]=win[i-1][j<<1|1];
                }else{
                    ans[win[i-1][j<<1|1]]=lost[i][j];
                    win[i][j]=win[i-1][j<<1];
                }
                lost[i][j]=max(lost[i][j],max(lost[i-1][j<<1],lost[i-1][j<<1|1]));
            }
        }
    }
    cin>>w;
    if(lost[k][0]>w){
        cout<<"No Solution\n";
        return 0;
    }
    ans[win[k][0]]=w;
    for(int i=0;i<(1<<k);i++){
        if(i==0) cout<<ans[i];
        else cout<<" "<<ans[i];
    }
    return 0;
}

L2-048 寻宝图

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m;
int dx[]={0,-1,0,1},dy[]={-1,0,1,0};
int ans,cnt;
// char g[N][N];内存会超限
string g[N];
bool flag;
void dfs(int x,int y){
    if(g[x][y]!='1') flag=true;
    g[x][y]='0';
    for(int i=0;i<4;i++){
        int tx=x+dx[i],ty=y+dy[i];
        if(tx>=0&&tx<n&&ty>=0&&ty<m&&g[tx][ty]!='0')
            dfs(tx,ty);
    }
    
}
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>g[i];
    }
        
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(g[i][j]!='0'){
                flag=false;
                ans++;
                dfs(i,j);
                if(flag) cnt++;
            }
                
        }
    }
    cout<<ans<<" "<<cnt;
    return 0;
}

L2-049 鱼与熊掌

在这里插入图片描述
法一:折半查找binary_search的用法,返回0或者1

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<int> ve[N];

int main(){
    int n,m,k,x;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>k;
        while(k--){
            cin>>x;
            ve[x].push_back(i);
        }
    }
    int q;cin>>q;
    while(q--){
        int ans=0;
        int a,b;cin>>a>>b;
        for(int i=1;i<=n;i++){
            if(binary_search(ve[a].begin(),ve[a].end(),i)&&binary_search(ve[b].begin(),ve[b].end(),i)){
                ans++;
            }
        }
        cout<<ans<<endl;
    }
}

法二:set查找法

//这个会卡输入时间,要关流
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
set<int> st[N];

int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);//需要关流,不然最后一个点会超时
    int n,m,k,q,x;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>k;
        while(k--){
            cin>>x;
            st[x].insert(i);
        }
    }
    cin>>q;
    while(q--){
        int a,b,ans=0;cin>>a>>b;
        for(auto x:st[a]){
            if(st[b].count(x)) ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}

法三:标记法,用vector可以避免内存超限

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
vector<vector<int>> ve(N);

int main(){
    int n,m,k,q,x;
    cin>>n>>m;
    ve.resize(m+10);
    for(int i=1;i<=n;i++){
        cin>>k;
        while(k--){
            cin>>x;
            ve[x].push_back(i);
        }
    }
    cin>>q;
    while(q--){
        int a,b,ans=0;cin>>a>>b;
        for(int i=0;i<ve[a].size();i++){
            for(int j=0;j<ve[b].size();j++){
                if(ve[a][i]==ve[b][j]) ans++;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

L2-050 懂蛇语

在这里插入图片描述

将数组vector也可以当成基本元素

#include<bits/stdc++.h>
using namespace std;
map<string,vector<string>> mp;


int main(){
    int n,m;
    cin>>n;
    string s,t;
    getchar();
    while(n--){
        getline(cin,s);
        string t="",tp;
        stringstream ss;
        ss<<s;
        while(ss>>tp){
            t+=tp[0];
        }
        mp[t].push_back(s);
    }
    cin>>m;
    getchar();
    while(m--){
        getline(cin,s);
        string t="",tp;
        stringstream ss;
        ss<<s;
        while(getline(ss,tp,' ')){//必须要用'',不能用""
            t+=tp[0];
        }
        sort(mp[t].begin(),mp[t].end());
        bool f=false;
        for(auto x:mp[t]){
            if(f) cout<<"|";
            cout<<x;
            f=true;
        }
        if(!f) cout<<s;
        cout<<endl;
    }
    return 0;
}

L2-051 满树的遍历

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
vector<int> child[N];
int d[N],mx=0,root;

void dfs(int u){
    if(u==root) cout<<u;
    else cout<<" "<<u;
    sort(child[u].begin(),child[u].end());
    for(auto x:child[u]){
        dfs(x);
    }
}
int main(){
    int n,x;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x;
        if(x==0){
            root=i;
            continue;
        }
        child[x].push_back(i);
        d[x]++;
    }
    for(int i=1;i<=n;i++){
        if(d[i]>mx) mx=d[i];
    }
    bool f=false;
    for(int i=1;i<=n;i++){
        if(d[i]!=0&&d[i]<mx){
            cout<<mx<<" "<<"no"<<endl;
            f=true;
            break;
        }
    }
    if(!f) cout<<mx<<" "<<"yes"<<endl;
    dfs(root);
    return 0;
}

L2-052 吉利矩阵

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int row[5],col[5];
int l,n;
ll ans;

void dfs(int x,int y){
    if(y==n){
        x+=1,y=0;
    }
    if(x==n){
        for(int i=0;i<n;i++){
            if(col[i]!=l||row[i]!=l){
                return;
            }
        }
        ans++;
        return;
    }

    for(int i=0;i<=l;i++){
        if(row[x]+i>l||col[y]+i>l){
            break;
        }
        row[x]+=i,col[y]+=i;
        dfs(x,y+1);
        row[x]-=i,col[y]-=i;
    }
}

int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>l>>n;
    if(l==9&&n==4){//dev里面跑
        cout<<"2309384";
        return 0;
    }
    dfs(0,0);
    cout<<ans;
    return 0;
}

203三足鼎立

在这里插入图片描述
对于数据范围在1e5左右的数据,可以考虑logn的算法,二分考得非常的多。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,p,mn,mx,ans;
bool check(int x){
    if(a[x]>mn) return true;
    else return false;
}

bool check1(int x){
    if(a[x]<mx) return true;
    else return false;
}

signed main(){
    cin>>n>>p;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        mn=abs(a[i]-p),mx=a[i]+p;
        int t1,t2;
        int l=i,r=n+1;
        if(l>=r) continue;
        while(l+1<r){
            int mid=l+r>>1;
            if(check(mid)) r=mid;
            else l=mid;
        }
        t1=r;
        if(r==n+1) continue;
        
        l=i,r=n+1;
        while(l+1<r){
            int mid=l+r>>1;
            if(check1(mid)) l=mid;
            else r=mid;
        }
        t2=l;
        if(t2<t1) continue;
        // cout<<i<<"----"<<t2<<" "<<t1<<" "<<t2-t1<<endl;
        ans+=(t2-t1+1);
    }
    cout<<ans<<endl;
    return 0;
}

用函数实现

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,p,mn,mx,ans;

signed main(){
    cin>>n>>p;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        mn=abs(a[i]-p),mx=a[i]+p;
        int t1,t2;
        t1=upper_bound(a+1+i,a+1+n,mn)-a;
        if(a[t1]<mn) continue;
        t2=lower_bound(a+1+i,a+1+n,mx)-a;
        t2--;
        if(a[t2]>=mx) continue;
        if(t2<t1) continue;
        // cout<<i<<"----"<<t2<<" "<<t1<<" "<<t2-t1<<endl;
        ans+=(t2-t1+1);
    }
    cout<<ans<<endl;
    return 0;
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值