Codeforces Round #499 (Div. 2)(A~E)

A

用一个布尔数组存储每个字母是否出现过。
我们贪心的想,如果有两个连续的字母,我们选第一个肯定比第二个优
直接扫一遍就行了

#include<bits/stdc++.h>
using namespace std;
int n , k;
char s[100];
bool flag[30];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
int main()
{
    n = read();k = read();
    scanf("%s",s+1);
    int now = 0 , num = 0;
    int len = strlen(s+1);
    for(int i = 1;i <= len;++i)
        flag[s[i] - 'a' + 1] = true;
    for(int i = 1;i <= 26;++i)
    {
        if(flag[i]) 
            now += i , num++ , i++;
        if(num == k) break;
    }
    if(num < k) printf("-1");
    else printf("%d",now);
    return 0;
} 

B

数据很小,根本不用二分。
直接从小到大枚举答案,对数列排个序,考虑每一个数能贡献多少个组
不满足就输出答案

#include<bits/stdc++.h>
using namespace std;
int n , m;
int a[200];
struct node{
    int num , kind;
}sum[200];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
bool mycmp(node a,node b)
{
    return a.num > b.num;
}
bool check(int x)
{
    int ss = 0;
    for(int i = 1;i <= 100;++i)
        ss += (sum[i].num / x);
    if(ss >= n) return true;
    else return false;
}
int main()
{
    n = read();m = read();
    for(int i = 1;i <= 100;++i)
        sum[i].kind = i; 
    for(int i = 1;i <= m;++i)
        a[i] = read() , sum[a[i]].num++;
    sort(sum + 1,sum + 101 , mycmp);
    int ans = 0;
    for(int i = 1;i <= 100;++i)
        if(!check(i)) break;
            else ans = i;
    printf("%d",ans);
    return 0;
} 

C

题意有点绕
要耗费最小,我们显然可以发现最后正好用完油
列方程逆推即可
注意a或b为1无解

#include<bits/stdc++.h>
using namespace std;
int n , m;
int a[1100];
int b[1100];
int c[2100];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
void work()
{
    double now = 1.0 * m;bool flag = true;
    for(int i = 1;i <= 2 * n;++i)
    {
    //  printf("%d %.8lf\n",c[i],now);
        int k = c[i] - 1;
        if(c[i] == 1){
            printf("-1");
            return;
        }
        now = now + now / (1.0 * k);
    }
    printf("%.8lf",now - m);
    return;
}
int main()
{
    n = read();m = read();
    for(int i = 1;i <= n;++i)
        a[i] = read();
    for(int i = 1;i <= n;++i)
        b[i] = read();
    int k = 0;
    c[++k] = b[1];
    for(int i = n;i >= 2;--i)
    {
        c[++k] = a[i];
        c[++k] = b[i];
    } 
    c[++k] = a[1];
    work();
    return 0;
} 

D

我们可以先输出n个1或n骗出序列。
然后正常二分就行了

#include<bits/stdc++.h>
using namespace std;
int n , m;
bool flag[40];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
void work()
{
    int l = 1 , r = m;
    int k = 0;
    while(l + 1< r)
    {
        k++;
        k = k % n;
        int mid = (l + r) / 2;
        printf("%d\n",mid);
        fflush(stdout);
        int x = read();
        if(!flag[k]) x = -x;
        if(x == 0||x == 2) exit(0);
        if(x == 1) l = mid + 1;
         else r = mid - 1;
    }
    printf("%d\n",r);
    fflush(stdout);
    int x = read();
    if(x == 0) exit(0);
    printf("%d\n",l);
    fflush(stdout);
    x = read();
    if(x == 0) exit(0);
    return;
}
int main()
{
    m = read();n = read();
    for(int i = 1;i <= n;++i)
    {
        printf("1\n");
        fflush(stdout);
        int x = read();
        if(x == 0) exit(0);
        if(x == 1) flag[i] = true;
    }
    flag[0] = flag[n];
    work();
    return 0;
} 

E

被谷歌翻译坑了cccccc
看成了每种只能用一次,上bitset,仔细一算发现会超时…
如果用无数次就好想了
裴蜀定理。
那我们只要求出GCD,然后枚举倍数不停对k取模即可。

#include<bits/stdc++.h>
using namespace std;
int n , k;
bool flag[101000];
int read()
{
    int sum = 0;char c = getchar();bool flag = true;
    while( c < '0' || c > '9' ) {if(c == '-') flag = false;c = getchar();}
    while( c >= '0' && c <= '9' ) sum = sum * 10 + c - 48 , c = getchar();
    if(flag)  return sum;
     else return -sum;
}  
int gcd(int a,int b){return (!b) ? a : gcd(b,a%b);}
int main()
{
    n = read();k = read();
    int now = read();
    for(int i = 2;i <= n;++i)
    {
        int x = read();
        now = gcd(now , x);
    } 
    now %= k;
    int t = now;
    while(!flag[t])
    {
        flag[t] = true;
        t = (now + t) % k; 
    }
    int sum = 0;
    for(int i = 0;i < k;++i)
        if(flag[i]) sum++;
    printf("%d\n",sum);
    for(int i = 0;i < k;++i)
        if(flag[i]) printf("%d ",i);
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值