ACM 实验室2020.10.10天梯赛练习*2

7-3 N个数求和 (20分)

自己当时光做第一题,导致没空做第三题,自己稍微一做就过了,但是还是出了一点错误。

写出来之后一直有一两个点不过,结果发现自己的符号添加错误,因为按照我写的代码,不用自己添加符号输出就可以,但是我自己写的符号判断是错误的,导致有些情况下会报错。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+10;

int main(){
    ll n,x,u,d,a[101],b[101];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        getchar();
        cin>>b[i];

    }
    for(int i=0;i<n-1;i++){
        ll g,lg;
        g=__gcd(b[i],b[i+1]);
        lg=b[i]/g*b[i+1];
        a[i+1]=a[i]*(lg/b[i])+a[i+1]*(lg/b[i+1]);
        b[i+1]=lg;
    
    }
    if(a[n-1]%b[n-1]==0)
        cout<<a[n-1]/b[n-1]<<endl;
    else if(a[n-1]<b[n-1]){
        
        cout<<a[n-1]%b[n-1]/__gcd(a[n-1]%b[n-1],b[n-1])<<"/"<<b[n-1]/__gcd(a[n-1]%b[n-1],b[n-1])<<endl;
    }
    else{
        cout<<a[n-1]/b[n-1]<<" ";
        
        cout<<a[n-1]%b[n-1]/__gcd(a[n-1]%b[n-1],b[n-1])<<"/"<<b[n-1]/__gcd(a[n-1]%b[n-1],b[n-1])<<endl;
    }
    return 0;
}

7-10 链表去重 (25分)

没学过数据结构,对链表的运用不是很熟悉,自己之前稍微学过一点,看了题结果想不到如何用一个链表做题,因为想不到一段链表如何分成两段来写。

只想到链表可以用next指向,没想到可以使用数组链表,记录下标来做。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+10;


struct node{
    int key;
    int next;
};

node a1[MAXN];

int a2[MAXN],a3[MAXN];
bool flag[MAXN];


int main(){
    int m,n;
    cin>>m>>n;
    
    int addr,key,next;
    for(int i=0;i<n;i++){
        cin>>addr;
        cin>>a1[addr].key;
        cin>>a1[addr].next;
    }
    memset(flag,true,sizeof(flag));
    int k1=0,k2=0;
    for(int i =m;i!=-1;i=a1[i].next){
        int q=abs(a1[i].key);
        if(flag[q]){
            flag[q]=false;
            a2[k1++]=i;
        }
        else{
            a3[k2++]=i;
        }
    }
    printf("%05d %d ",a2[0],a1[a2[0]].key);
    for(int i =1;i<k1;i++){
        printf("%05d\n",a2[i]);
        printf("%05d %d ",a2[i],a1[a2[i]].key);
    }
    cout<<"-1"<<endl;
    if(k2){
        printf("%05d %d ",a3[0],a1[a3[0]].key);
        for(int i=1;i<k2;i++){
            printf("%05d\n",a3[i]);
            printf("%05d %d ",a3[i],a1[a3[i]].key);
        }
        cout<<"-1"<<endl;
    }
    
    return 0;
}

 

7-11 部落 (25分)

普通的并查集,就是要把每行第一个和所有的结合一下。

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

ll f[MAXN],n,m,k,a[MAXN];
int find(int x){
    if(x==f[x])
        return x;
    else
        return f[x]=find(f[x]);
}

void merge(int x,int y){
    int t1=find(x);
    int t2=find(y);
    if(t1!=t2)
        f[t2]=t1;
}

int main(){
    for(int i =0;i<MAXN;i++){
        f[i]=i;
    }
    
    
    cin>>n;
    int ans2=0,ans1=0;
    for(int ii =1;ii<=n;ii++){
        cin>>k;
        int p;
        cin>>p;
        a[p]=1;
        for(int i =1;i<k;i++){
            int x;
            cin>>x;
            a[x]=1;
            merge(p,x);
        }    
    }
    for(int i =1;i<10001;i++){
        
        if(a[i]==1){
            ans1++;
        } 
    }
    for(int i =1;i<=ans1;i++){
        if(f[i]==i)
            ans2++;
    }
    cout<<ans1<<" "<<ans2<<endl;
    cin>>m;
    while(m--){
        ll xx,yy;
        cin>>xx>>yy;
        if(find(xx)==find(yy)){
            cout<<"Y"<<endl;
        }
        else
            cout<<"N"<<endl;
    }

    return 0;
}

 

posted @ 2020-10-15 09:25  Leviathan_Sei  阅读(108)  评论(0)    收藏  举报