暑假训练第三周第四天

题意:
A CodeForces 1217D:给定一个无自环、无多重边的有向图。好染色图的定义:如果一个有向图每条边都有颜色,并且一个环中不止有一种颜色,那么这个图称为一个好染色图。现在要你求最少多少种颜色,可以把给定的有向图染成好染色图。
B CodeForces 1217A:给出str,int,exp问在用完exp的条件下,有多少情况使得改变之后的str>int。
C CodeForces 1217B:t组数据,n个攻击力,刚开始恶龙有x个头,每个攻击力di。hi,意思是可以砍掉di个头,然后有长出了hi个头
D CodeForces 1217C:给定一个只包含0,1的字符串s,问在这个字符串当中,有多少个子串s[l-r]满足demical(s[l-r])=r-l+1,即子串长度等于它所表示的十进制数。
E CodeForces 1213A:n个数,每个数可以加减2,或者花钱加减1,让所有数相同要多少钱。
F CodeForces 1213C:在[1, n]这个区间内,若存在某个数 i 是m的倍数,则把 i 的个位数加起来的和sum进行输出
G CodeForces 1213B:求坏天,即求该天之后有没有比该天价格更低的一天,求这种天的天数
H CodeForces 1213D1: 给n个数,每次可以把其中一个数字位运算右移一位(即整除以二),问要至少操作几次才能让这n个数中有至少k个相等。
题解:
A:题解
B:思路:一开始想着在str大于int的前提下,循环统计,超时了。然后用柱形图模拟了一下,可以分成三种情况:1、常规情况:(str+exp-int+1)/2。2、str>int+exp:有exp+1种情况。3、str+exp<int:情况数为0。
代码:

#include <bits/stdc++.h>
using namespace std;
int t,s,in,ex,sum;
int main()
{
cin>>t;
while(t--){
    cin>>s>>in>>ex;
    sum=0;
    if(s+ex<=in)
    cout<<0<<endl;
	else
        cout<<min((s+ex-in+1)/2,ex+1)<<endl;
}
}

C:思路:记录最大攻击力和最大差值,分三种情况:1、最大攻击力大于当前头数时,输出1。2、最大差值小于等于0,输出-1。3、正常情况:(当前头数-最大攻击力+最大差值-1)/最大差值+1。
代码:

#include <bits/stdc++.h>
using namespace std;
int t,x,n,maxi,sum;
struct y{
int h;
int d;
int c;}
a[110];
bool cmp(y e,y b){
return e.c>b.c;}
int main()
{
cin>>t;
while(t--){
    cin>>n>>x;
    maxi=0;
    sum=0;
    for(int i=1;i<=n;i++){
        cin>>a[i].d>>a[i].h;
        a[i].c=a[i].d-a[i].h;
        maxi=max(maxi,a[i].d);
    }
    sort(a+1,a+1+n,cmp);
    if(maxi>=x)
        sum=1;
    else
        if(a[1].c<=0)
        sum=-1;
    else
   sum=(x-maxi+a[1].c-1)/a[1].c+1;
    cout<<sum<<endl;
}
}

E:思路:找到奇数个数和偶数个数较小的数。
代码:

#include <bits/stdc++.h>
using namespace std;
int n,x,j,o;
int main()
{
cin>>n;
j=0;
o=0;
while(n--){
    cin>>x;
    if(x%2==0)
    o++;
    else
        j++;
}
cout<<min(j,o)<<endl;
}

F:思路:m在一定次数时取余会开始循环,假设他们都为10次循环,只需要算出多余次数的和。加上前面部分10次的和。
代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int main(void) {
    LL q;
    cin>>q;
    while(q--) {
        LL n, m;
        scanf("%lld %lld", &n, &m);
        LL sum = 0;
        for(LL i = 0;i < 10;i++)
            sum += (m * i % 10);
        LL cnt = n / m / 10;
        LL r = n / m % 10;
        LL num = sum * cnt;
        for(LL i = 1;i <= r;i++)
            num += (m * i % 10);
        printf("%lld\n", num);
    }
    return 0;
}

G:思路:从后面往前找,有比后面这个标记的数还小的数再标记这个更小的数。
代码:

#include <bits/stdc++.h>
using namespace std;
int t,n,a[150010],sum,i,f;
int main()
{
    cin>>t;
    while(t--)
    {
        sum=0;
        cin>>n;
        for(i=0; i<n; i++)
            cin>>a[i];
            f=a[n-1];
        for(i=n-2; i>=0; i--)
        {

            if(f<a[i])
            {
                sum++;
            }
            else
                if(f>a[i])
            {
                f=a[i];
            }
        }
       cout<<sum<<endl;;
    }
}

H:思路:排序一遍之后统计每个数出现了多少次,出现k次的时候更新一遍答案。
代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 50;
int cnt[N];
int num[N];
int a[N];
int main() {
    int n, k;
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    sort(a + 1, a + n + 1);
    int res = 1e9;
    for (int i = 1; i <= n; i++) {
        int tmp = 0;
        while (a[i]) {
            cnt[a[i]]++;
            num[a[i]] += tmp;
            if (cnt[a[i]] == k) {
                res = min(res, num[a[i]]);
            }
            tmp++; a[i] /= 2;
        }
    }
    printf("%d\n", res);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值