zoukankan      html  css  js  c++  java
  • CF练习记录

    2018/5/6
    Codeforces Round #478 (Div. 2) C
    http://codeforces.com/contest/975/problem/C
    Valhalla Siege

    题意:n的士兵,每个士兵有一些生命值,有q次询问,每次询问从前向后造成ki点贯穿伤害(生命值归零的士兵死去,后续士兵承受溢出伤害),问每次询问有几个士兵还活着。当所有士兵死去时,不继续造成溢出伤害并且所有士兵复活。

    思路:二分搜索,对士兵生命值求前缀和,每次询问造成的伤害累计,记为s,用upper_bound来寻找前缀和中大于s的第一个人的位置i,n-i就是剩下的人数,如果剩下的人数为0(死完了),就全部复活,s清0。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int MAX_N = 200000 + 8;
     5 ll x[MAX_N];
     6 ll sum[MAX_N];
     7 int main()
     8 {
     9     int i,n,q;
    10     cin >> n >> q;
    11 
    12     memset(sum,0x3f,sizeof(sum));
    13     for(i=0;i<n;i++){
    14         cin >> x[i];
    15         if(i)
    16             sum[i]=sum[i-1]+x[i];
    17         else
    18             sum[i]=x[i];
    19     }
    20     ll s=0,tmp;
    21     for(i=0;i<q;i++){
    22         cin >> tmp;
    23         s+=tmp;
    24         int index=upper_bound(sum,sum+MAX_N,s)-sum;
    25         if(n-index<=0)
    26         {
    27             s=0;
    28             index=0;
    29         }
    30         cout << n-index << "
    ";
    31     }
    32     return 0;
    33 }
    View Code

     Codeforces Round #476 (Div. 2) 

    http://codeforces.com/contest/965/problem/C

    D<=1000,因此可以简单枚举,每次最大一定是n/((i-1)*k+1) * i,但是有很多情况需要特判排除。

    题解,https://www.cnblogs.com/AWCXV/p/8949119.html

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 
     6 int main()
     7 {
     8     ios_base::sync_with_stdio(false);
     9     cin.tie(0);
    10     ll  n,k,M,D;
    11     cin  >> n >> k >> M >> D;
    12     ll ans=M;
    13     for(ll i=2;i<=D;i++)
    14     {
    15         ll x=n/((i-1)*k+1);
    16 
    17         if(x==0)break;
    18         if(x>M)x=M;
    19         if ((n/(k*x)+((n%(k*x)>=x?1:0)))!=i) continue;
    20         ans=max(ans, x*i);
    21     }
    22     cout << ans << "
    ";
    23 
    24     return 0;
    25 }
    View Code

     2018/5/17

    http://codeforces.com/contest/984/problem/C

    题意:给出p,q,b,求b进制下p/q是否为无穷小数。

    思路:先用gcd将p/q化为真分数,再对于q和b:由于p和q互质,之后的过程就与p无关了。

    由于是b进制,每进一位就相当于原小数*b,那么这个过程中就相当于q/gcd(q,b)。持续到q和gcd(q,b)其中一个为1即可。

    一开始直接用快速幂……超时,%lld CF不能用CE。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 
     6 ll gcd(ll x,ll y){
     7     return y==0?x:gcd(y,x%y);
     8 }
     9 
    10 
    11 int main()
    12 {
    13     ios::sync_with_stdio(false);
    14     cin.tie(0);
    15     ll p,q,b;
    16     int n;
    17     cin >> n;
    18     while(n--){
    19         cin >> p >> q >>b;
    20         ll x=p/gcd(p,q);
    21         ll y=q/gcd(p,q);
    22         ll cheek=gcd(y,b);
    23         while(y!=1&&cheek!=1){
    24             while(y%cheek==0)y/=cheek;
    25             cheek=gcd(b,y);
    26         }
    27         if(y==1)
    28             cout << "Finite
    ";
    29         else
    30             cout << "Infinite
    ";
    31     }
    32 }
    View Code

    2018/5/22

    http://codeforces.com/contest/982

    B

    【题意】:

    就是说有一辆公交车,有n排;

    接下来n个数据代表n排的权值(每排只能坐2个人);

    然后接下来又2*n的数据

    代表要坐入这辆公交车的人的类型。

    1代表外向型,0代表内向型。

    外向型:优先选择旁边有人的且权值最大的位置,如果没有的话,选择权值最大的位置。

    内向型:优先选择没人的位置且权值最小的位置。

    【思路】:

    首先定义座位的属性:

    状态:0代表旁边没人,1代表旁边有人。

    第几排

    权值

    维护两个优先队列

    优先队列0,用于维护旁边没人的座位,权值最小的排在最前面。

    优先队列1,用于维护旁边有人的座位,权值最大的排在最前面。

    一开始座位都没人,都存入队列0.

    每次操作,从相应队列找最前面的位置,若队列0中找到座位,则将座位的状态改变存入队列1.

    之后删除相应队列中的该座位。

    输出即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 struct node{
     6     int state;
     7     int row;
     8     int pow;
     9     node(int s,int r,int p):state(s),row(r),pow(p){};
    10     node(){}
    11 };
    12 
    13 struct rule0{
    14     bool operator()(const node &a,const node &b){
    15         return a.pow<b.pow||a.pow==b.pow&&a.row<b.row;
    16     }
    17 };
    18 
    19 struct rule1{
    20     bool operator()(const node &a,const node &b){
    21         return a.pow>b.pow||a.pow==b.pow&&a.row<b.row;
    22     }
    23 };
    24 
    25 int main(){
    26     set<node,rule1> st1;
    27     set<node,rule0> st0;
    28     set<node,rule0>::iterator it0;
    29     set<node,rule1>::iterator it1;
    30 
    31     int n;
    32     cin >> n;
    33     int pow;
    34     for(int i=0;i<n;i++){
    35         cin >> pow;
    36         node tmp(0,i+1,pow);
    37         st0.insert(tmp);
    38     }
    39     string people;
    40     cin >> people;
    41     for(int i=0;people[i];i++){
    42         if(people[i]=='0'){
    43             it0=st0.begin();
    44             if(it0!=st0.end()){
    45                 node tmp=*it0;
    46                 st0.erase(it0);
    47                 tmp.state++;
    48                 st1.insert(tmp);
    49                 printf("%d%c",tmp.row,i==2*n-1?'
    ':' ');
    50                 continue;
    51             }
    52             else{
    53                 it1=st1.begin();
    54                 node tmp=*it1;
    55                 st1.erase(it1);
    56                 printf("%d%c",tmp.row,i==2*n-1?'
    ':' ');
    57                 continue;
    58             }
    59 
    60         }
    61         else {
    62             it1=st1.begin();
    63             if(it1==st1.end()){
    64                 it0=st0.begin();
    65                 node tmp=*it0;
    66                 st0.erase(it0);
    67                 tmp.state++;
    68                 st1.insert(tmp);
    69                 printf("%d%c",tmp.row,i==2*n-1?'
    ':' ');
    70                 continue;
    71             }
    72             else{
    73                 node tmp=*it1;
    74                 st1.erase(it1);
    75                 printf("%d%c",tmp.row,i==2*n-1?'
    ':' ');
    76                 continue;
    77             }
    78         }
    79     }
    80 }
    View Code

    C

    题意:https://www.cnblogs.com/kickit/p/9054233.html

    给出一棵树,问最多去掉多少条边之后,剩下的连通分量的size都是偶数。

    思路:

    如果本来就是奇数个点,那么无论去掉多少条边都不可能成立的。

    如果是偶数个点,就进行一次dfs,假设一个点的父亲是u,儿子是v,那么可以去掉(u,v)的条件就是v及其子树有偶数个点,任何一条这样的边都是可以去掉的。

    所以一边dfs,一边统计答案就可以了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int n;
     5 vector<int> v[100010];
     6 int ret;
     7 int dfs(int u,int f){
     8     int ans=1;
     9     for(int i=0;i<v[u].size();i++){
    10         if(v[u][i]!=f){
    11             int tmp=dfs(v[u][i],u);
    12             if(tmp%2==0)ret++;
    13             ans+=tmp;
    14         }
    15     }
    16     return ans;
    17 }
    18 
    19 int main(){
    20     cin >> n;
    21     if(n&1){
    22         cout << -1 <<endl;
    23         return 0;
    24     }
    25 
    26     int x,y;
    27     int start=-1;
    28     for(int i=1;i<n;i++){
    29         cin >>x >>y;
    30         v[x].push_back(y);
    31         v[y].push_back(x);
    32     }
    33     dfs(1,-1);
    34     cout << ret <<endl;
    35 }
    View Code

    479 C

    阴险的陷阱题……

    题意:

    给一些数,范围从1到1e9,问是否存在一个数,使得正好有k个数小于等于这个数

    思路:

    很容易想到排序,前k个数一定是选入的,只要判断第k+1个数是否等于第k个数即可。

    然而……WA了

    问题在于k可以取0.

    范围是从1开始的,所以还要判断这种情况下最小的数是否大于1,以上。 

    codeforces.com/contest/977

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 int main(){
     6     int x[200010];
     7     int n,k;
     8     while(cin >> n >> k){
     9         memset(x,0x3f,sizeof(x));
    10         for(int i=0;i<n;i++){
    11             cin >> x[i];
    12         }
    13         sort(x,x+n);
    14         if(k==0){
    15             if(x[0]>1)
    16                 printf("1
    ");
    17             else
    18                 printf("-1
    ");
    19             continue;
    20         }
    21         else if(x[k]!=x[k-1])
    22             printf("%d
    ",x[k-1]);
    23         else
    24             printf("-1
    ");
    25 
    26     }
    27 }
    View Code

    Educational Codeforces Round 42

    C. Make a Square

    http://codeforces.com/contest/962/problem/C

    题意:给一个无前导零的数,你可以删除任意多的数字,使得它成为一个无前导零的平方数……吗?若可以,输出最少操作数,若不可以,输出-1.

    思路:

    混乱……

    开玩笑的,今天状态太差了,这么一道破水题卡了我一个小时,我还看题解了……

    总之,题目很简单,暴力枚举,数据范围2e9,枚举所有可能情况最多也就1024种情况,每种情况判断是否无前导零、是否为平方数(开根号平方等于本身)即可。

    一开始zz想用ac自动机被卡、情况0未考虑被卡、前导零未考虑被卡……

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <string>
     5 #include <iostream>
     6 #include <math.h>
     7 using namespace std;
     8 
     9 int main()
    10 {
    11     int i,j,tmp;
    12     string t;
    13     cin >> t;
    14     int flag=0,ans=0;
    15     for(i=1;i<(1<<t.size());i++){
    16         tmp=i;
    17         int s=0;
    18         j=0;
    19         int num=0;
    20         while(tmp>0){
    21             if( !(!s&&t[j]=='0') && (tmp&1) ){
    22                 s=s*10+t[j]-'0';
    23                 num++;
    24             }
    25             j++;
    26             tmp>>=1;
    27         }
    28         if(s&&(int)sqrt(s)*(int)sqrt(s)==s ){
    29             ans=max(ans,num);
    30             flag=1;
    31         }
    32     }
    33     if(!flag){
    34         printf("-1
    ");
    35     }
    36     else
    37         printf("%d
    ",t.size()-ans);
    38     return 0;
    39 }
    View Code

    5.24

    http://codeforces.com/contest/985

    越写越觉得自己是zz……

    1.水题暴力即可,没考虑排序……

     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 int abs(int x){
     5     return x > 0 ? x : -x;
     6 }
     7 
     8 int main()
     9 {
    10     int n;
    11     int x[110];
    12     cin >> n ;
    13     for(int i=0;2*i<n;i++){
    14         cin >> x[i];
    15     }
    16     sort(x,x+n/2);
    17     int a=0,b=0;
    18     for(int i=0;2*i<n;i++){
    19         a+=abs(2*i+2-x[i]);
    20     }
    21     for(int i=0;2*i<n;i++){
    22         b+=abs(2*i+1-x[i]);
    23     }
    24     printf("%d
    ",min(a,b));
    25     return 0;
    26 }
    View Code

    2.水题

     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 int x[2010]={0};
     6 string a[2010];
     7 int main()
     8 {
     9     int n,m,flag,yes=0;
    10     cin >> n  >> m;
    11     for(int i=0;i<n;i++){
    12         cin >> a[i];
    13         for(int j=0;a[i][j];j++){
    14             if(a[i][j]=='1')
    15                 x[j]++;
    16         }
    17     }
    18     for(int i=0;i<n;i++){
    19         flag=1;
    20         for(int j=0;a[i][j];j++){
    21             if(a[i][j]=='1'&&x[j]<2){
    22                 flag=0;
    23             }
    24         }
    25         if(flag){
    26             yes=1;
    27             printf("YES
    ");
    28             break;
    29         }
    30     }
    31     if(!yes){
    32         printf("NO
    ");
    33     }
    34     return 0;
    35 }
    View Code

    3.贪心

    确定能选的范围,之后每次选能选到的最大的。

    爆int,用long long

     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 typedef long long ll;
     5 ll x[100010];
     6 int main()
     7 {
     8     int n,k,l;
     9     cin >> n >> k >> l;
    10     for(int i=0;i<n*k;i++){
    11         cin >> x[i];
    12     }
    13     sort(x,x+n*k);
    14     int index=upper_bound(x,x+n*k,x[0]+l)-x;
    15 //    cout << index <<endl;
    16     if(index<n){
    17         printf("0
    ");
    18         return 0;
    19     }
    20     ll sum=0;
    21 //    for(int i=0;i<n*k;i++)
    22 //        printf("%d	",x[i]);
    23 
    24     for(int i=0;n&&i<index;){
    25         sum+=x[i];
    26         i+=min(k,max(index-i-n+1,1));
    27         n--;
    28 //        printf("index-i-n+1:%d
    ",index-i-n+1);
    29 //        printf("i:%d
    ",i);
    30     }
    31     cout << sum << endl;
    32     return 0;
    33 }
    View Code

    5.25

    1.水题,注意n==0的情况即可

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     long long n;
     8     cin >> n;
     9     if(!n){
    10         cout << 0 << endl;
    11         return 0;
    12     }
    13     n++;
    14     
    15     if(n%2==0)
    16         cout <<n/2 <<endl;
    17     else
    18         cout << n << endl;
    19     return 0;
    20 }
    View Code

    2.贪心,注意特殊情况,全部相同字符情况n==1时减少一位

     1 #include <iostream>
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     string a[3];
     8     int num;
     9     cin >> num >> a[0] >> a[1] >> a[2];
    10     int ch[3][300]={0};
    11     for(int j=0;j<3;j++){
    12 
    13         for(int i=0;a[j][i];i++){
    14             ch[j][ a[j][i] ]++;
    15             ch[j][0]=max(ch[j][0],ch[j][a[j][i]]);
    16         }
    17         if(num==1&&ch[j][0]==(int)a[j].size()){
    18             ch[j][0]--;
    19             continue;
    20         }
    21         ch[j][0]=min(ch[j][0]+num,(int)a[j].size());
    22 
    23     }
    24     int maxn=max(max(ch[0][0],ch[1][0]),ch[2][0]);
    25     if(maxn==ch[0][0]&&maxn==ch[1][0]||
    26        maxn==ch[0][0]&&maxn==ch[2][0]||
    27        maxn==ch[2][0]&&maxn==ch[1][0])
    28         cout << "Draw
    ";
    29     else if(maxn==ch[0][0])
    30         cout << "Kuro
    ";
    31     else if(maxn==ch[1][0])
    32         cout << "Shiro
    ";
    33     else if(maxn==ch[2][0])
    34         cout << "Katie
    ";
    35 
    36     return 0;
    37 }
    View Code
  • 相关阅读:
    2017.7.27
    js 变量那些事
    JS初学之-效果没出来怎么办?-alert函数测试
    JS初学之-循环生成坐标
    JS初学之-if else图片顺序及循环切换
    JSP笔记与案例一览(JSP后半部分)
    Java基础一览(会不断补充)
    session和cookie一览
    request和response一览
    封装含义一览
  • 原文地址:https://www.cnblogs.com/bestefforts/p/8997640.html
Copyright © 2011-2022 走看看