zoukankan      html  css  js  c++  java
  • Codeforces Round #702

    A:给定一个序列,一个操作是向其中任何一个位置插入一个数,问至少需要多少次操作才能保证两两之间的max(a[i],a[i+1])/min(a[i],a[i+1])<=2。

      假设在i和i+1之间插入一个数,这个操作并不会影响到其他,所以我们可以线性的考虑整个序列。

      那么我们现在只需要考虑如果a和b,max(a,b)/min(a,b)>2的话怎么办。

      只需要一直在a,b之间插入a的2次方倍,直到满足条件就OK了。

     1 #include<iostream>
     2 using namespace std;
     3 int main(void){
     4     int t;
     5     cin>>t;
     6     while(t--){
     7         int a[100];
     8         int n;
     9         cin>>n;
    10         for(int i=0;i<n;i++){
    11             cin>>a[i];
    12         }
    13         int res=0;
    14         for(int i=0;i<n-1;i++){
    15             int t1=min(a[i],a[i+1]),t2=max(a[i],a[i+1]);
    16             while(t1*2<t2){
    17                 res++;
    18                 t1*=2;
    19             }
    20         }
    21         cout<<res<<endl;
    22     }
    23     return 0;
    24 }

    B:给定一串序列,按模3的余数分类,每次操作可以将其中一个数加一,问最少多少次操作可以保证每一类的数目相等(保证总数模3等于0)

    首先计算出每一类的数目,0->1,1->2,2->0,都只需要一次操作。

    直接计算即可。

     1 #include<iostream>
     2 using namespace std;
     3 int main(void){
     4     int t;
     5     cin>>t;
     6     while(t--){
     7         int n;
     8         scanf("%d",&n);
     9         int cnt[3]={0,0,0};
    10         for(int i=0;i<n;i++){
    11             int tmp;
    12             scanf("%d",&tmp);
    13             cnt[tmp%3]++;
    14         }
    15         int s=(cnt[0]+cnt[1]+cnt[2])/3;
    16         int res=0;
    17         for(int i=0;i<3;i++){
    18             if(cnt[i]<s){
    19                 int tmp=s-cnt[i];
    20                 res+=tmp;
    21                 cnt[(i-1+3)%3]-=tmp;
    22             }else{
    23                 int tmp=cnt[i]-s;
    24                 res+=tmp;
    25                 cnt[(i+1+3)%3]+=tmp;
    26             }
    27         }
    28         cout<<res<<endl;
    29     }
    30     return 0;
    31 }

    C:给定一个数x,问x=a^3+b^3的a和b是否存在。

    x的范围是1e12,开三次方就是1e4,所以可以预处理出1~1e4的三次方。

    然后对于每一个x,枚举a,在预处理数组中二分查找b。

    时间复杂度为1e4*log(1e4)。

     1 #include<cmath>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 typedef long long LL;
     6 const int N=10100;
     7 int cnt;
     8 LL a[N];
     9 bool is_ok(LL x){
    10     int l=0,r=cnt-1;
    11     while(l<r){
    12         int mid=l+r+1>>1;
    13         if(a[mid]>x) r=mid-1;
    14         else l=mid;
    15     }
    16     return a[r]==x;
    17 }
    18 int main(void){
    19     for(LL i=1;i<=10010;i++){
    20         a[cnt++]=i*i*i;
    21     }
    22     int t;
    23     cin>>t;
    24     while(t--){
    25         bool flag=false;
    26         LL x;
    27         cin>>x;
    28         for(LL i=1;i*i*i<x;i++){
    29             LL a=i*i*i;
    30             LL b=x-a;
    31             if(is_ok(b)){
    32                 flag=true;
    33             }
    34         }
    35         if(flag) cout<<"YES"<<endl;
    36         else cout<<"NO"<<endl;
    37     }
    38     return 0;
    39 }

    D:给定一个排列,每次选择最大的那个数,建立一棵二叉树,输出每个节点的深度。

    考试的时候想的是先建出一棵树,然后再层序遍历,可惜我用的是静态数组(因为方便),那么假设他给你的就是单单的一条链的话,100个节点就需要2^100的数组长度(显然不行)。

    我们在建树的时候存储的是它在原数组中的位置,那么我们可以直接传一个depth参数进去,对于每一个节点直接确定他的深度,就不存在空间的问题了。

     1 #include<iostream>
     2 #include<queue>
     3 #include<climits>
     4 #include<cstring>
     5 using namespace std;
     6 typedef pair<int,int> PII;
     7 const int N=1110;
     8 int a[N],res[N];
     9 int b[N*4];
    10 void build(int root,int l,int r){
    11     if(l>r) return ;
    12     int ma=a[l],id=l;
    13     for(int i=l;i<=r;i++){
    14         if(a[i]>ma){
    15             ma=a[i],id=i;
    16         }
    17     }
    18     b[root]=id;
    19     build(root*2+1,l,id-1);
    20     build(root*2+2,id+1,r);
    21 }
    22 int main(void){
    23     int t;
    24     cin>>t;
    25     while(t--){
    26         memset(b,0,sizeof b);
    27         int n;
    28         cin>>n;
    29         for(int i=1;i<=n;i++){
    30             cin>>a[i];
    31         }
    32         build(0,1,n);
    33         queue<int> q;
    34         q.push(0);
    35         int deep=0;
    36         while(q.size()){
    37             int s=q.size();
    38             for(int i=0;i<s;i++){
    39                 int x=q.front();
    40                 q.pop();
    41                 res[b[x]]=deep;
    42                 if(b[x*2+1]!=0){
    43                     q.push(x*2+1);
    44                 }
    45                 if(b[x*2+2]!=0){
    46                     q.push(x*2+2);
    47                 }
    48             }
    49             deep++;
    50         }
    51         for(int i=1;i<=n;i++){
    52             cout<<res[i]<<" ";
    53         }
    54         cout<<endl;
    55     }
    56     return 0;
    57 }
    错误的建树之后再层序遍历的代码
     1 #include<iostream>
     2 #include<queue>
     3 #include<climits>
     4 #include<cstring>
     5 using namespace std;
     6 typedef pair<int,int> PII;
     7 const int N=1010;
     8 int a[N],d[N];
     9 void build(int l,int r,int depth){
    10     if(l>r) return ;
    11     int id=l;
    12     for(int i=l;i<=r;i++){
    13         if(a[i]>a[id]){
    14             id=i;
    15         }
    16     }
    17     d[id]=depth;
    18     build(l,id-1,depth+1);
    19     build(id+1,r,depth+1);
    20 }
    21 int main(void){
    22     int t;
    23     cin>>t;
    24     while(t--){
    25         int n;
    26         cin>>n;
    27         for(int i=1;i<=n;i++){
    28             cin>>a[i];
    29         }
    30         build(1,n,0);
    31         for(int i=1;i<=n;i++){
    32             cout<<d[i]<<" ";
    33         }
    34         cout<<endl;
    35     }
    36     return 0;
    37 }

    E(补):给定n个选手和他们各自的value,每次随机选定两个选手,value大的获胜并获得败者的全部value,如果两者value相等,胜负将随机。共进行n-1次比赛,每次仅仅选择手中还有value的上场。

        输出有最终可能获胜的人的人数和所有最终有可能获胜的人的编号(从小到大)。

        将选手按value排序并记住他们的id,如果 i 赢完了小于他的全部的选手的value,还是无法战胜最小的大于他的,那么 i 获胜的几率就为0.

        如此便可以直接用前缀和解决这个问题。

     1 #include<iostream>
     2 #include<queue>
     3 #include<climits>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 typedef long long LL;
     8 const LL N=2e5+10;
     9 struct node{
    10     LL v,id;
    11     bool operator< (node& t){
    12         return v<t.v;
    13     }
    14 }a[N];
    15 LL sum[N];
    16 int main(void){
    17     LL t;
    18     cin>>t;
    19     while(t--){
    20         LL n;
    21         vector<LL> res;
    22         cin>>n;
    23         for(LL i=1;i<=n;i++){
    24             cin>>a[i].v;
    25             a[i].id=i;
    26         }
    27         sort(a+1,a+n+1);
    28         for(int i=1;i<=n;i++){
    29             sum[i]=sum[i-1]+a[i].v;
    30         }
    31         res.push_back(a[n].id);
    32         for(LL i=n-1;i>=1;i--){
    33             if(sum[i]>=a[i+1].v){
    34                 res.push_back(a[i].id);
    35             }else{
    36                 break;
    37             }
    38         }
    39         sort(res.begin(),res.end());
    40         cout<<res.size()<<endl;
    41         for(auto x:res){
    42             cout<<x<<" ";
    43         }
    44         cout<<endl;
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14416979.html
Copyright © 2011-2022 走看看