zoukankan      html  css  js  c++  java
  • [题解]2018湘潭邀请赛

    A.Easy h-index

    题目描述

    The h-index of an author is the largest h where he has at least h papers with citations not less than h.
    Bobo has published many papers. Given a0, a1, a2 ,..., an which means Bobo has published a i papers with citations exactly i , find the h-index of Bobo.

    输入

    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test case contains an integer n . The second line contains ( n + 1) integers a0 , a1 , ... , an .

    输出

    For each test case, print an integer which denotes the result.
    • 1 ≤ n ≤ 2 · 105
    • 0 ≤ ai ≤ 109
    • The sum of n does not exceed 250,000.

    样例输入

    1
    1 2
    2
    1 2 3
    3
    0 0 0 0
    

    样例输出

    1
    2
    0
    
    题意:给定被引用次数为0~n的论文分别有几张,找到最大的h,满足被引用次数大于等于h的论文至少有h张
    思路:在区间[0,n]内二分答案;或直接从n~0遍历找到第一个满足条件的h
    AC代码:
    #include <iostream>
    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    
    ll n;
    ll a[200010];
    
    bool ok(ll x){
      ll cnt=0;//cnt的值可能会爆int
      for(ll i=0;i<=n;i++) if(i>=x) cnt+=a[i];
      if(cnt>=x) return true;
      return false;
    }
    
    int main()
    {
        while(cin>>n){
            for(ll i=0;i<=n;i++){
                cin>>a[i];
            }
            ll l=0,r=n;
            while(l<=r){
                ll mid=(l+r)/2;
                if(ok(mid)) l=mid+1;
                else r=mid-1;
            }
            cout<<r<<endl;
        }
        return 0;
    }
    View Code

    B.Higher h-index

    题目描述

    The h-index of an author is the largest h where he has at least h papers with citations not less than h .
    Bobo has no papers and he is going to publish some subsequently. If he works on a paper for x hours, the paper will get (a·x ) citations from other other persons, where a is a known constant. It’s clear that x should be a positive integer. 
    There is also a trick – one can cite his own papers published earlier.
    Given Bobo has n working hours, find the maximum h-index of him.

    输入

    The input consists of several test cases and is terminated by end-of-file.
    Each test case contains two integers n and a .

    输出

    For each test case, print an integer which denotes the maximum h-index.
    • 1 ≤ n ≤ 109
    • 0 ≤ a ≤ n
    • The number of test cases does not exceed 104 .

    样例输入

    3 0
    3 1
    1000000000 1000000000
    

    样例输出

    1
    2
    1000000000
    

    提示

    For the first sample, Bobo can work 3 papers for 1 hour each. With the trick mentioned, he will get papers with citations 2 , 1 , 0. Thus, his h-index is 1.
    For the second sample, Bobo can work 2 papers for 1 and 2 hours respectively. He will get papers with citations 1 + 1 , 2 + 0. Thus, his h-index is 2.

    题意:给定n个小时,可以用其中x(1<=x<=n)个小时写一篇论文,那么这篇论文的"既定"引用数将会是x*a(a为给定正整数);此外,已经写好的论文将会被其后写成的论文所引用,也就是说,这篇论文的总引用数将会是"既定"引用数+其后论文篇数;问在所有的写论文方案中(例如一种方案就是用n个小时写n篇论文,每篇论文各花1小时(可以得到这n篇论文的引用数)),h最大为多少(h的含义同上题)(每一种方案都对应着一个h,求这些h中的最大者)

    思路:最优方案(即对应h值最大的方案)是平摊n小时写成n篇论文(证明未知);此时n篇论文的引用数为a,a+1,a+2,...,a+n-1,引用数为a+i时,引用数大于等于它的论文有n-i篇,令a+i=n-i得i=(n-a)/2,所以h=a+(n-a)/2;

    AC代码:

    #include<cstdio>
    
    int main(){
       int n,a;
       while(scanf("%d%d",&n,&a)!=EOF){
        printf("%d
    ",a+(n-a)/2);
       }
       return 0;
    }
    View Code

    C.Just h-index

    D.Circular Coloring

    E.From Tree to Graph

    F.Sorting

    题目描述

    Bobo has n tuples ( a1 , b1 , c1 ) , ( a2 , b2 , c2 ) , . . . , ( an , bn , cn ). He would like to find the lexicographically smallest permutation p1 , p2 , . . . , pn of 1 ,2 , . . . , n such that for i ∈ {2 , 3 , . . . , n} it holds that

    输入

    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test case contains an integer n . The i-th of the following n lines contains 3 integers ai,bi and ci .

    输出

    For each test case, print n integers p1, p2,..., pn seperated by spaces. DO NOT print trailing spaces.
    Constraint
    • 1 ≤ n ≤ 103
    • 1 ≤ ai , bi , ci ≤ 2 × 109
    • The sum of n does not exceed 104 .

    样例输入

    2
    1 1 1
    1 1 2
    2
    1 1 2
    1 1 1
    3
    1 3 1
    2 2 1
    3 1 1
    

    样例输出

    2 1
    1 2
    1 2 3

    题意:给定n个元组(a1,b1,c1),(a2,b2,c2),...,(an,bn,cn),将其按(ai+bi)/(ai+bi+ci)的值从小到大排序,输出排序后的n个元组的原序号;
    思路:编写sort里的cmp函数(形参为元组结构体元素,设为Tuple x,Tuple y),若直接算出(x.a+x.b)*(y.a+y.b+y.c)和(y.a+y.b)*(x.a+x.b+x.c)再比较大小,这两个结果会爆unsigned long long;
    可以把因式乘积展开成多项式的和,约去两式中相同的项,得到x.a*y.c+x.b*y.c和y.a*x.c+y.b*x.c,因此只需计算它俩再比较即可,结果不会爆unsigned long long
    AC代码:
    #pragma GCC optimize(2)
    #include<iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <set>
    using namespace std;
    
    struct Tuple{
      long long a,b,c;
      int ind;
    }tup[100010];
    
    bool cmp(Tuple x,Tuple y){
      unsigned long long l=x.a*y.c+x.b*y.c;
      unsigned long long r=y.a*x.c+y.b*x.c;
      if(l==r) return x.ind<y.ind;
      return l<r;
    }
    
    int main(){
      int n;
      while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++){
            cin>>tup[i].a>>tup[i].b>>tup[i].c;
            tup[i].ind=i;
        }
        sort(tup+1,tup+1+n,cmp);
        for(int i=1;i<=n;i++){
            if(i!=1) printf(" ");
            cout<<tup[i].ind;
        }
        printf("
    ");
      }
      return 0;
    }
    View Code

    G.String Transformation

    题目描述

    Bobo has a string S = s1 s2...sn consists of letter a , b and c . He can transform the string by inserting or deleting substrings aa , bb and abab .
    Formally, A = u ◦ w ◦ v (“ ◦ ” denotes string concatenation) can be transformed into A 0 = u ◦ v and vice versa where u , v are (possibly empty) strings and w ∈ { aa , bb , abab } .
    Given the target string T = t1 t2 . . . tm , determine if Bobo can transform the string S into T .

    输入

    The input consists of several test cases and is terminated by end-of-file.
    The first line of each test case contains a string s1 s2 ...sn . The second line contains a string t1 t2 . . . tm .

    输出

    For each test case, print Yes if Bobo can. Print No otherwise.
    • 1 ≤ n, m ≤ 104
    • s1 , s2 ,..., sn , t1 , t2 , . . . , tm ∈ { a , b , c }
    • The sum of n and m does not exceed 250,000.

    样例输入

    ab
    ba
    ac
    ca
    a
    ab
    

    样例输出

    Yes
    No
    No
    

    提示

    For the first sample, Bobo can transform as ab => aababb => babb => ba .

    题意:给定字符串S和T(均只由a,b,c三个字母组成),可对S进行插入或删除操作(插入或删除的子串只能是"aa","bb"或"abab"),问能否通过操作将S变为T

    思路:发现经过操作一定可将ab—>ba、ba—>ab(等价于相邻的ab可以互换位置),那么我们以c为分隔点将S划分为若干小段,对每一个小段,一定可以通过互换相邻a,b的操作使a全在一边,b全在一边,两两约去a,两两约去b,得到“化简”后的小段(可能其中有一个"ab"或有一个'a'或有一个'b'或为空);就这样分别将每一个小段都“化简”,而原来c的位置不动,得到整个化简后的S;对T进行同样的“化简”操作;若化简后的S,T相同,则Yes,否则No

    AC代码:

    #include <iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
     
    char s1[1000010];
    char s2[1000010];
    char tmp1[1000010];
    char tmp2[1000010];
     
    int main()
    {
        while(scanf("%s%s",s1,s2)!=EOF){
            int len=strlen(s1);
            int cnt_1=0,cnt_2=0;
            int cnt_a=0,cnt_b=0;
            for(int i=0;i<len;i++){
                if(s1[i]=='c') {
                    if(cnt_a%2==0&&cnt_b%2==0) ;
                    else if(cnt_a%2==1&&cnt_b%2==0) tmp1[++cnt_1]='a';
                    else if(cnt_a%2==0&&cnt_b%2==1) tmp1[++cnt_1]='b';
                    else {tmp1[++cnt_1]='a'; tmp1[++cnt_1]='b';}
                    tmp1[++cnt_1]='c';
                    cnt_a=0; cnt_b=0;
                }
                else if(s1[i]=='a') cnt_a++;
                else cnt_b++;
            }
            if(cnt_a%2==0&&cnt_b%2==0) ;
            else if(cnt_a%2==1&&cnt_b%2==0) tmp1[++cnt_1]='a';
            else if(cnt_a%2==0&&cnt_b%2==1) tmp1[++cnt_1]='b';
            else {tmp1[++cnt_1]='a'; tmp1[++cnt_1]='b';}
            cnt_a=0; cnt_b=0;
            len=strlen(s2);
            for(int i=0;i<len;i++){
                if(s2[i]=='c') {
                    if(cnt_a%2==0&&cnt_b%2==0) ;
                    else if(cnt_a%2==1&&cnt_b%2==0) tmp2[++cnt_2]='a';
                    else if(cnt_a%2==0&&cnt_b%2==1) tmp2[++cnt_2]='b';
                    else {tmp2[++cnt_2]='a'; tmp2[++cnt_2]='b';}
                    tmp2[++cnt_2]='c';
                    cnt_a=0; cnt_b=0;
                }
                else if(s2[i]=='a') cnt_a++;
                else cnt_b++;
            }
            if(cnt_a%2==0&&cnt_b%2==0) ;
            else if(cnt_a%2==1&&cnt_b%2==0) tmp2[++cnt_2]='a';
            else if(cnt_a%2==0&&cnt_b%2==1) tmp2[++cnt_2]='b';
            else {tmp2[++cnt_2]='a'; tmp2[++cnt_2]='b';}
            cnt_a=0; cnt_b=0;
            if(cnt_1!=cnt_2) printf("No
    ");
            else{
                int flag=0;
                for(int i=1;i<=cnt_1;i++){
                    if(tmp1[i]!=tmp2[i]) {flag=1;break;}
                }
                if(flag) printf("No
    ");
                else printf("Yes
    ");
            }
        }
        return 0;
    }
    View Code

    H.Infinity

    I.Longest Increasing Subsequence

    J.Vertex Cover

    K.2018

    题目描述

    Given a, b, c, d , find out the number of pairs of integers ( x, y ) where a ≤ x ≤ b, c ≤ y ≤ d and x · y is a multiple of 2018.

    输入

    The input consists of several test cases and is terminated by end-of-file.
    Each test case contains four integers a, b, c, d 

    输出

    For each test case, print an integer which denotes the result.
    • 1 ≤ a ≤ b ≤ 109 , 1 ≤ c ≤ d ≤ 109
    • The number of tests cases does not exceed 104 .

    样例输入

    1 2 1 2018
    1 2018 1 2018
    1 1000000000 1 1000000000
    

    样例输出

    3
    6051
    1485883320325200

    题意:给定区间[a,b]、[c,d],问有多少对有序数组(x,y)(x∈[a,b],y∈[c,d])使得x*y是2018的倍数
    思路:2018=2*1009(分解质因数),则对x分类讨论:1)仅为2的倍数;2)仅为1009的倍数;3)即为2又为1009的倍数;4)既不为2又不为1009的倍数
    等价于如下分类讨论:
    1.若x是偶数:1)若x是1009的倍数,则y可为[c,d]中任意数; 2)若x不是1009的倍数,则y必定为[c,d]中1009的倍数
    2.若x是奇数:1)若x是1009的倍数,则y必定为[c,d]中2的倍数; 2)若x不是1009的倍数,则y必定为[c,d]中2018的倍数
    AC代码:
    #include<cstdio>
    #include<iostream>
    typedef unsigned long long ll;
    using namespace std;
    
    int main(){
       ll a,b,c,d;
       while(cin>>a>>b>>c>>d){
         ll num1_all_1009=b/1009-(a-1)/1009;
         ll num1_even=b/2-(a-1)/2;
         ll num1_1009_in_even=b/2018-(a-1)/2018;
         ll num1_rest_in_even=num1_even-num1_1009_in_even;
         ll num1_odd=(b-a+1)-num1_even;
         ll num1_1009_in_odd=num1_all_1009-num1_1009_in_even;
         ll num1_rest_in_odd=num1_odd-num1_1009_in_odd;
         ll ans=0;
         ans+=num1_1009_in_even*(d-c+1);
         ll num2_all_1009=d/1009-(c-1)/1009; ans+=num1_rest_in_even*num2_all_1009;
         ll num2_even=d/2-(c-1)/2; ans+=num1_1009_in_odd*num2_even;
         ll num2_all_2018=d/2018-(c-1)/2018; ans+=num1_rest_in_odd*num2_all_2018;
         cout<<ans<<endl;
       }
       return 0;
    }
    View Code
    转载请注明出处:https://www.cnblogs.com/lllxq/
  • 相关阅读:
    IntelliJ IDEA java项目导入jar包,打jar包
    intelliJ idea运行新的test功能时,报错:class not found "....." empty test suite
    WEBSERVICE之JDK开发webservice
    Linux uname 命令 打印系统信息
    IDEA中 @override报错的解决方法
    使用VMware搭建3台一模一样的Linux虚拟机
    java使用httpclient封装post请求和get的请求
    在Centos中yum安装和卸载软件的使用方法
    JAVA面试题:69道Spring面试题和答案
    JAVA面试题:equals()方法和== 区别
  • 原文地址:https://www.cnblogs.com/lllxq/p/9057738.html
Copyright © 2011-2022 走看看