五一题单

五一题单https://vjudge.net/contest/436484#problem

 

1.https://vjudge.net/contest/436484#problem/J

 

J题wa了好多发,思路挺简单,就是很多细节需要注意。

 

题意:给定字符串中第一个“ * ”和最后一个都要变成“ x ”,然后给定一个数字k,最多隔k个数要有一个x。

 

思路:从前从后分别遍历一次,找到第一个*和最后一个*变成x,然后从第一个*开始遍历,每隔k个字符就需要有一个x,注意x只能由*改变而来,因此记录下x的位置下一个的k个判断就从记录的这里开始了,直接两个循环就行,注意数据范围,j的值是不能大于n的。

 

代码:

#include<stdio.h>
#include<string.h>
int main()
{
    int t,n,k;
    char str[105];
    scanf("%d",&t);
    while(t--){
        int cnt=0;
        int fg1,fg2;
        scanf("%d %d",&n,&k);
        getchar();
        gets(str);
        for(int i=0;i<n;i++){
            if(str[i]=='*'){
                str[i]='x';
                cnt++;
                fg1=i;
                break;
            }
        }
        for(int i=n-1;i>=0;i--){
            if(str[i]=='*'){
                str[i]='x';
                cnt++;
                break;
            }
        }
        for(int i=fg1;i<n;i++){
            if(str[i]=='x'){
                int fg=0;
                for(int j=i+k;j>i&&j<n;j--){
                    if(str[j]=='x'){
                        i=j-1;
                        fg=1;
                        break;
                    }
                }
                if(fg==0){
                    for(int j=i+k;j>i&&j<n;j--){
                        if(str[j]=='*'){
                            i=j-1;
                            str[j]='x';
                            cnt++;
                            break;
                        }
                    }    
                }
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

 

2.https://vjudge.net/contest/436484#problem/C

 

C题主要也是理解题意,理清思路(刚开始没有想到的时候感觉还是有点懵)。

题意:在一个数组里面,如果gcd(a,b)的结果为数组里的最小值就可以交换a和b的位置,如果能形成升序输出yes否则no。

 

思路:需要是gcd(a,b)结果为数组最小值,那么a或者b就是数组最小值,假设a是最小值,那么为了使gcd(a,b)=a,就需要b是a的倍数。

我们可以把所给数组sort排个序看成一个新的数组,将这个数组与原数组对比,如果有元素是不一样的,就判断是否是通过交换而来的,如果是通过交换得来的,就yes,否则no。

 

代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t,n;
    int a[100005],b[100005];
    scanf("%d",&t);
    while(t--){
        int fg=0,x=1e9;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
            x=min(x,a[i]);
        }
        sort(b,b+n);
        for(int j=0;j<n;j++){
            if(a[j]!=b[j]&&a[j]%x!=0){
                printf("NO\n");
                fg=1;
                break;
            }
        }
        if(fg==0)
        printf("YES\n");
    }
    return 0;
}

 

3.https://vjudge.net/contest/436484#problem/E

 

题意:给出一个数组,让你将其分为n个一组,共k组,使每一组的中位数的和最大。(向上取中位数)

 

思路:从后往前隔k个取数尽量要大。

 

代码:

#include<stdio.h>
#include<string.h>
long long a[1000005];
int main()
{
    long long t,n,k,m;
    scanf("%lld",&t);
    while(t--){
        long long fg1,fg2,sum=0;
        scanf("%lld %lld",&n,&k);
        m=n*k;
        for(long long i=1;i<=m;i++){
            scanf("%lld",&a[i]);
        }
        fg1=n/2+1;
        fg2=m-fg1;
        for(long long j=fg2+1;k;j-=fg1,k--)
        sum+=a[j];
        printf("%lld\n",sum);
    }
    return 0;
}

 

4.https://vjudge.net/contest/436484#problem/D

 

D题题意:给出一个字符串,其中只有0和1两种数字,数字分别有其价格,可以将0变为1,1变为0,变化有一定价格,最后将所有的数字都买了求最小需要多少价格。

 

思路:比较简单,当变化的价格比0和1的差值大的时候就亏了,所以不变,当变化价格小于1和0的差值时,最后只有一种数字,加上变化的价格就是最终的总价格。

 

代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t,n,a,b,c;
    int c0,c1,h;
    char str[1005];
    scanf("%d",&t);
    while(t--){
        int fg1=0,fg2=0;
        scanf("%d %d %d %d",&n,&c0,&c1,&h);
        getchar();
        gets(str);
        for(int i=0;i<n;i++){
            if(str[i]=='0')
            fg1++;
            else
            fg2++;
        }
        a=c0-c1;
        if(a<0)
        a=-a;
        if(a<=h)
        printf("%d\n",fg1*c0+fg2*c1);
        else{
            if(c0>c1)
            printf("%d\n",c1*n+fg1*h);
            else
            printf("%d\n",c0*n+fg2*h);
        }
    }
    return 0;
}

 

5.https://vjudge.net/contest/436484#problem/F

 

题意&思路(好好学英语):一个数组有n个数字,每个数字转换成二进制有k位,并且每个数按位与后为0且和最大。按位与为0的话就需要每一位都得有至少一个0(按位与为0的情况:1,0;0,1;0,0)。因为要保证最大所以只有一个0就够了,最后求得有多少个这样的数组。又因为n^k太大了要用快速幂处理一下。(注意有long long)

 

快速幂部分代码:

while(k){
            if(k&1){
                ans = (ans*n)%N;
            }
            n = (n*n)%N;
            k>>=1;
        }

 

all:

#include<stdio.h>
int main()
{
    long long t,n,k,cnt;
    scanf("%lld",&t);
    int x=1e9+7;
    while(t--){
        cnt=1;
        scanf("%lld %lld",&n,&k);
        while(k){
            if(k&1){
                cnt=cnt*n%x;
            }
            n=n*n%x;
            k>>=1;
        }
        printf("%lld\n",cnt);
    }
    return 0;
}

 

to be continued......

posted @ 2021-05-05 18:07  Untergehen  阅读(37)  评论(0编辑  收藏  举报