• HPU第一次团队赛


    D. Tom的战力问题

    Tom揍了TAT。
    Tom下定决心要战胜
    但是在战胜最强的之前,Tom要先打败其他的狗。为此,他打算先收集一下信息。
    现在Tom在了得到了一些关于战斗力的小道消息,例如X号狗狗的战力比Y号狗狗的战力高S点。
    Tom想知道利用这些消息,能不能判断出某两只狗之间的战力高低?高多少?

    输入格式

    第一行包含三个整数N,MQN表示狗总数,M表示Tom知道消息的总数,Q表示小Tom想询问的数量。  

    以下M行每行三个整数,X,YS。表示X号狗的战力比Y号狗的战力高S点。  

    以下Q行每行两个整数,XY。表示Tom想知道X号狗的战力比Y号狗的战力高几点。  
    2N1000 
    1M,QN 
    1X,YN 
    1000S1000

    数据保证没有矛盾。

    输出格式

    对于每个询问,如果不能判断出XY高几点输出1。否则输出XY高多少战力点。

    样例

    input
    10 5 3
    1 2 10
    2 3 10
    4 5 -10
    5 6 -10
    2 5 10
    1 10
    1 5
    3 5
    
    output
    -1
    20
    0
    其实就是一个简单的BFS问题。题目中问两个狗之间的站力相差多少,我们可以看成路径问题即A到B的距离为C,B到A的距离为-C,然后跑图,不可到大的话输出-1
     #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N=1e3+7;
    int n,m,q;
    
    struct stu{
        int a,b;
    };
    vector<stu >ve[N];
    int mark[N];
    bool check=false ;
    int f=-1;
    
    void bfs(int x,int y){
        memset(mark,0,sizeof(mark));
        queue<stu >que;
        que.push({x,0});
        mark[x]=1;
        while(que.size()){
            stu aa=que.front();
            que.pop();
    //        cout<<aa.a<<endl;
            if(aa.a==y){
                f=aa.b;
                break;
            }
            for(int i=0;i<ve[aa.a].size();i++){
                if(mark[ve[aa.a][i].a]==0){
                    mark[ve[aa.a][i].a]=1;
                    que.push({ve[aa.a][i].a,aa.b+ve[aa.a][i].b});
                }
            }
        }
    }
    
    
    int main(){
        scanf("%d%d%d",&n,&m,&q);
        int x,y,z;
        
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            ve[x].push_back({y,z});
            ve[y].push_back({x,-z});
        }
        
        
        while(q--){
             f=-1;
             int x,y;
             scanf("%d%d",&x,&y);
             bfs(x,y);
             printf("%d
    ",f);
        } 
        
        return 0;
    } 

    E  Tom的函数求值

    众所周知,Tom不会递归,但是今天他突然顿悟了!并且凭借自己的能力写出了下面这段代码:

    int F(int m,int n)
    {
        if(!m)
            return n+1;
        if(!n&&m)
            return F(m-1,1);
        if(m&&n)
            return F(m-1,F(m,n-1));
    }
    

    现在,他想让你根据这个函数来解决问题

    输入格式

    单组输入,每组一行,有两个整数mn(0m3,0n27)

    输出格式

    请输出上面代码的运行结果

    样例

    input
    1 1
    
    output
    3
    
    input
    0 1
    
    output
    2
    

    提示

    如果不知道怎么做的话,不妨试试直接把代码复制粘贴进去吧٩̋(ˊ•͈ ꇴ •͈ˋ)و

    对于这种类型的题目,我们可以先运行一下它给出的代码,然后输出一些值,在找规律。

    //int F(int m,int n)
    //{
    //    if(!m)
    //        return n+1;
    //    if(!n&&m)
    //        return F(m-1,1);
    //    if(m&&n)
    //        return F(m-1,F(m,n-1));
    //}
    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    // m==0  n+1;
    // m==1  2 3 4
    // m==2  3 5 7
    // m==3  5 13 29
    ll f(ll x){
        if(x==0) return 5;
        else return 2*f(x-1)+3;
    }
    int main(){
        ll a,b;
        scanf("%lld %lld",&a,&b);
        if(a==0) printf("%d",b+1);
        else if(a==1) printf("%d
    ",b+2);
        else if(a==2) printf("%d
    ",2*b+3); 
        else if(a==3) printf("%lld
    ",f(b));
        return 0;
    } 

    FTom的约会

    XX协会又要迎来新的成员了。

    这次的妹子颇多,足足有n人之多(1n106),她们每个人的学号都是1018 内的一个正整数。

    Jerry 早早地就掌握了她们每个人的学号,并且知道她们之中有一个人和Tom约会去了!

    Jerry 统计了在场所有妹子的学号,他想知道,哪个人没来?

    输入格式

    第一行是一个整数n,代表一共有n只妹纸

    以下n行每行一个整数,代表每只妹纸的学号

    接下来一个空行

    以下n1行每行一个整数,代表每只来了的妹纸的学号

    输出格式

    输出没来的妹纸的学号。

    样例

    input
    3
    10061061
    10061023
    10061201
    
    10061023
    10061201
    
    output
    10061061
    

    提示

    开头别想着抢一血,稳着跟榜做题,很多队伍过的题自己卡住了别慌,肯定不是特别难的算法,多换几个思路,上个厕所调整一下状态,总之,心态要好~
    ~~ 以上都是废话 ~~

    看到这个题目,觉得用map比较好,但是TLE了,,用map没TLE的是卡过去的,这里可以开个两个数组,存完值后进行排序,找到第一个不向等的,就可以退出了,

    也可以用无序字典

    代码1:

    #include<iostream>
    #include<cstdio>
    #include<unordered_map>
    using namespace std;
    typedef long long ll;
    unordered_map<ll,int >mp;
    unordered_map<ll,int>::iterator it;
    int main(){
        int t;
        cin>>t;
        int t1=t-1;
        while(t--){
            ll x1;
            scanf("%lld",&x1);
            mp[x1]++;
        }
        while(t1--){
            ll y;
            scanf("%lld",&y);
            mp[y]++;
        }
        for(it=mp.begin();it!=mp.end();it++){
            if(it->second==1){
                printf("%lld
    ",it->first);
                break;
            } 
        }
        return 0;
    } 

    代码2:

    #include<cstdio>
    #include<algorithm> 
    #include<vector>
    using namespace std;
    typedef long long ll; 
    const int     N=1e6+7;
    ll p[N];
    ll p2[N];
    int main(){
        int t;
        scanf("%d",&t);
        ll x;
        for(int i=1;i<=t;i++){
            scanf("%lld",&p[i]);
        }
        for(int i=1;i<=t-1;i++){
            scanf("%lld",&p2[i]);
        }
        sort(p+1,p+1+t);
        sort(p2+1,p2+t);
        bool f=false ;
        for(int i=1;i<=t-1;i++){
            if(p[i]!=p2[i]){
                f=true;
                printf("%lld",p[i]);
                break; 
            }
        }
        if(!f) printf("%lld",p[t]);
        
        
        return 0;
    } 

    G. Tom爬楼梯

    Jerry 跑到了二楼,现在Tom面临的是一个n阶的楼梯,由于Tom的腿比较短,因此它一次只能爬1阶或2阶,机智的Jerry破坏掉了m阶楼梯,也就是说Tom无法踩在这m阶楼梯上,现在Tom想知道他有多少种方案能爬到第n阶楼梯。由于答案很大,输出方案数对109+7取模的结果。

    输入格式

    第一行输入一个T代表有T组输入,对于每组输入:
    第一行输入n,m,第二行输入m个数,第i个数ai代表第ai阶楼梯被破坏了。
    (1T,m10,1n1000,1ain)

    输出格式

    对于每组输入,输出方案数对109+7取模的结果。

    样例

    input
    3
    1 1
    1
    8 1
    1
    10 2
    1 2
    
    output
    0
    13
    0
    
     被这个题卡了好久,一开始的想法是计算每一个阶段的值,然后再相乘,但是不好写。。而且数据很大。。
    题解:用两个数组,第一个记录每个坏掉的楼梯,第一个记录两个楼梯之间正常楼梯的个数,这里注意开头要特殊处理。开头要保存正常楼梯个数加1。
    递推式:dp[1]=1,dp[2]=1.dp[n]=dp[n-1]+dp[n-2];
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    
    ll dp[1000+7];
    ll arr[1000+7];
    ll arr2[1000+7];
    
    void inint(){
        dp[1]=1;
        dp[2]=1;
        for(int i=3;i<=1000;i++){
            dp[i]=(dp[i-1]%mod+dp[i-2]%mod)%mod; 
        }
    }
    
    int main(){
        inint();
        int t;
        cin>>t;
        while(t--){
            ll a,b1;
            scanf("%lld%lld",&a,&b1);
            for(int i=1;i<=b1;i++){
                scanf("%lld",&arr[i]);
            }
            sort(arr+1,arr+1+b1);
    //         if(arr[b1]==a){
    //             puts("0");
    //             continue ;
    //         }
            int pos=0;
            arr2[pos++]=arr[1];
            for(int i=2;i<=b1;i++){
                arr2[pos++]=arr[i]-arr[i-1]-1;
            }
            arr2[pos++]=a-arr[b1];
            ll ans=1;
            for(int i=0;i<pos;i++){
                ans=(ans%mod*dp[arr2[i]]%mod)%mod;
            }
            cout<<ans<<endl;
        }
        
        return 0;
    }

    I. Jerry的数学题

    Tom自称是数学天才,无法忍受的Jerry 给 Tom 出了一道题,已知a,b,求解下列方程:

    {lcm(x,y)=agcd(x,y)=b

    Tom顿时傻眼了,现在只有你能来帮他挽回颜面了,快来帮帮它吧。

    输入格式

    第一行输入一个T代表有T组输入。
    每组输入包含两个正整数a,b
    (1T100,1a,b10000)

    输出格式

    对于每组输入,每行输出一组x,y,如果有多组,则输出x最小的,x,y中间用空格隔开。如果无解输出1

    样例

    input
    3
    100 50
    3 3
    6 7
    
    output
    50 100
    3 3
    -1
    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int a,b;
            scanf("%d%d",&a,&b);
            int x=a*b;
            bool check=false ;
            for(int i=b;i<=a;i+=b){
                int y=x/i;
                if(x%i==0&&__gcd(i,y)==b){
                    check=true;
                    if(y<i) swap(y,i);
                    printf("%d %d
    ",i,y);
                    break ; 
                }
            }
            if(!check) puts("-1");
        }
        
        return 0;
    }

    J. Jerry的题

    Jerry给Tom出了一道题,题目是这样的:
    **给出一棵n个节点的树,节点编号为1-n(根节点编号为1),每一个节点作为根节点与他所有的子孙节点形成一棵子树,而这棵子树包含节点的数量,称作子树的Size。

    例如:

    1─2─4─5
    └─3

    其中节点5的子树只包括节点5,Size = 1。节点4的子树包括节点4,5,Size = 2。节点1的子树包括节点1,2,3,4,5,Size = 5。

    求以所有节点为根的子树的Size之和。上面例子中,节点1到5,对应的Size分别为5,3,1,2,1,所有Size的和 = 5 + 3 + 1 + 2 + 1 = 12

    输入格式

    第一行:1个数n(1 < n <= 10000),表示树的节点数量。
    后面n-1行:每行2个数x y,表示节点x是节点y的父节点(1 <= x, y <= n)。

    输出格式

    输出1个数,表示以所有节点为根的子树的Size之和。

    样例

    input
    4
    1 2
    1 3
    2 4
    
    output
    8
    
     这个题目也是一个简单的BFS,我们只要记录每个点可以到达的 点的个数就可以了
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N=1E5+7;
    vector<int >ve[N];
    int step[N];
    bool mark[N];
    int ans=1;
    void bfs(int x){
        memset(mark,0,sizeof(mark));
        queue<int>que;
        que.push(x);
        mark[x]=1;
        step[x]=0;
    //    cout<<"x:"<<x<<endl;
        while(que.size()){
            int t=que.front();
            que.pop(); 
            for(int i=0;i<ve[t].size();i++){
    //            cout<<ve[t][i]<<"++"<<endl;
    //            ans++;
                if(mark[ve[t][i]]==0){
                    ans++; 
                    mark[ve[t][i]]=1;
                    step[ve[t][i]]=step[t]+1;
                    que.push(ve[t][i]);
                }
            }
        }
    }
    
    
    int main(){
        int t;
        cin>>t; 
        int x,y;
        for(int i=1;i<=t-1;i++)
        {
            cin>>x>>y;
            ve[x].push_back(y);
        }
        long long sum=0;
        for(int i=1;i<=t;i++){
            ans=1;
            bfs(i);
            sum+=1ll*ans;
        }
        cout<<sum<<endl;
        return 0;
    }

    L. Jerry的食粮

    公元9102年,Tom不再追逐Jerry,因为Tom的主人已经从China进口了很多猫粮,并且还有了智能抓老鼠机器。
    Jerry无处可躲,只能露宿街头。Tom不再缺乏食粮,但是可怜的小Jerry仍然还饥肠辘辘。
    这一天,小Jerry实在是饿坏了,再不吃点儿东西,他可能就横死街头了,于是,他想到了他的老朋友Tom,
    Tom这个糟老头子可是坏得很呀,他给小Jerry出了一个问题,做出来这个问题,小Jerry就能获得糟老头子Tom 
    赞助的补给!!!只有伟大的团队可以帮得了Jerry,并将获得荣耀之光,你们能帮可怜的Jerry获得补给吗?
    给定一个正整数n,求至少两个正整数使得他们的lcm(最小公倍数)为n,且这些正数的和最小,输出这个最小和。

    输入格式

    第一行一个整数T1T1e4
    接下来T行,每行一个正整数n1n2311

    输出格式

    输出T行,每行输出”Case #: “(不包括“”),#表示第#组数据,后面跟题目要求的答案,具体输出可参考样例

    样例

    input
    3
    12
    10
    5
    
    output
    Case 1: 7
    Case 2: 7
    Case 3: 6
    分解质因子,然后记录每个质因子构成的值,最后累加就好了,但是注意,,如果他的质因子个数只有一个,或者他是质数的话直接输出n+1
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=1e6+7;
    int prime[N]={1,1,0};
    ll pre[N];
    void f_prime(){
        int sum=0;
        for(int i=2;i<=N;i++){
            if(prime[i]==0){
                pre[sum++]=i; 
                for(int j=i+i;j<=N;j+=i){
                    prime[j]=1;
                }
            }
        }
    }
    
    int main(){
        f_prime();
        int t;
        int k=0;
        cin>>t;
        while(t--){
            k++;
            ll n;
            scanf("%d",&n);
            ll n1=n;
            printf("Case %d: ",k);
            if(n==1){
                printf("2
    ");
                continue ;
            }
            ll m=sqrt(n+1);
            ll ans=0;
            int x=0;
            for(int i=0;pre[i]<=m;i++){
                ll sum=1;
                if(n%pre[i]==0){
                    x++;
                    while(n%pre[i]==0){
                        sum*=pre[i];
                        n/=pre[i];
                    }
                    ans+=sum;
                }
            }
            if(n>1){
                x++;
                ans+=n;
            }
            if(x>1) {
                printf("%lld
    ",ans);
            }
            else {
                printf("%lld
    ",1+n1);
            }
        }
        return 0;
    } 


  • 相关阅读:
    TCP/IP三次握手四次挥手
    注解(JDK1.5之后)
    枚举(JDK1.5之后)
    局部内部类
    非静态内部类
    静态内部类
    匿名内部类
    接口
    根父类:java.lang.Object
    native关键字
  • 原文地址:https://www.cnblogs.com/Accepting/p/11396742.html
Copyright © 2020-2023  润新知