首页 > 其他 > 详细

05.18.习题训练一

时间:2020-05-20 10:57:03      阅读:47      评论:0      收藏:0      [点我收藏+]

A.Phoenix and Balance

 

题意:给一组数2^1,2^2,……,2^n,然后平均分为两组,使其两组和的差绝对值最小

思路:因为2^n增长很快,所以用2^n和最前面的数 (2^1,2^2,……)分为一组,剩下的n/2个数为一组,就是结果,并且列举几种情况出来的画,你就会发现式子可以化简

题解:

 1 #include<stdio.h>
 2 #include<math.h>
 3 int main(){
 4     int n,t;
 5     scanf("%d",&t);
 6     while(t--){
 7         scanf("%d",&n);
 8         n/=2;
 9         long long int sum=0,item=0;
10         item=pow(2,n);
11         sum+=2*(item-1);
12         printf("%lld\n",sum);
13     }
14 }

 

E.Nastay and Rice

题目:一共五个数n,a,b,c,d,计算(a-b)~(a+b),是否可以通过乘以n和(c-d)~(c+d)有交集

思路:直接进行计算,分情况:1.n*(a+b)在后面区间中;2.n*(a-b)在后面区域中;3.后面区域是前面区域乘完以后的子集

题解:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,a0,b0,c0,d0,a1,b1,c1,d1;
        scanf("%d %d %d %d %d",&n,&a0,&b0,&c0,&d0);
        a1=a0-b0;
        b1=a0+b0;
        c1=c0-d0;
        d1=c0+d0;
        if((a1*n>=c1&&a1*n<=d1)||(b1*n>=c1&&b1*n<=d1)||(a1*n<=c1&&b1*n>=d1)){
            printf("Yes\n");
        }else{
            printf("No\n");
        }
    }
}

 

F.Nastay and Door

题意:给你n,k,n个山峰值,山峰巅峰值就是这座山峰值比其他的都高,问在k个相连续的山峰中,山峰巅峰值个数是多少,并且这k个连续山峰中最左边的山峰坐标是多少

思路:再用一个数组,存入此位置是否是山峰巅峰值,是则为1,不是为1,则再用两层循环进行找巅峰值个数最多,并进行储存新的最左开始坐标

题解:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,k;
        int a[200005],b[200005]={0};
        scanf("%d %d",&n,&k);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<n-1;i++){
            if(a[i]>a[i-1]&&a[i]>a[i+1]){
                b[i]=1;
            }else{
                b[i]=0;
            }
        }

        int sum=0,item=0,h=1;
        for(int i=0;i<n-k+1;i++){
            item=0;
            for(int j=i+1;j<i+k-1;j++){
                item+=b[j];
            }
            if(item>sum){
                h=i+1;
                sum=item;
            }
        }
        printf("%d %d\n",sum+1,h);

    }
}

 

D.Binary Period

题意:给出01组成的字符串,进行寻找新的数组,并且已知数组可以通过对新数组的某个位置的数进行删除得到,并且使其是循环数组,循环的部分长度最短,总长度不超过2n

思路:单个循环的就直接输出即可,其他就限制在2n内输出01进行循环就可

题解:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 int main(){
 8     int t;
 9     scanf("%d",&t);
10     getchar();
11     while(t--){
12         char s[1100];
13         int s0=0,s1=0;
14         scanf("%s",&s);
15         int len;
16         len=strlen(s);
17         for(int i=0;i<len;i++){
18             if(s[i]==0){
19                 s0++;
20             }else{
21                 s1++;
22             }
23         }
24         if(s0==0||s1==0){
25             for(int i=0;i<len;i++){
26                 printf("%c",s[i]);
27             }
28             printf("\n");
29         }else{
30             int sum=max(s0,s1);
31             if(s[0]==0){
32                 for(int i=0;i<len;i++){
33                     printf("01");
34                 }
35                 printf("\n");
36             }else{
37                 for(int i=0;i<len;i++){
38                     printf("10");
39                 }
40                 printf("\n");
41             }
42         }
43     }
44 }

 

C.Road To Zero

 

题意:有两个数x,y,其中一个数增1或减1的话,需要花费a元,如果两个数一起减1或加1的话,需要花费b元,询问xy都变为0时花费的最少钱

思路:直接取最小,分出情况:1.以第一种为主;2.以第二种为主;

题解:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 int main(){
 7     long long int t,x,y,a,b;
 8     scanf("%lld",&t);
 9     while(t--){
10         long long int sum=0;
11         scanf("%lld %lld",&x,&y);
12         scanf("%lld %lld",&a,&b);
13 
14                 long long int temp;
15                 if(x>y){
16                     temp=x;
17                     x=y;
18                     y=temp;
19                 }
20                 sum=min(x*b+(y-x)*a,y*b+(y-x)*a);
21                 sum=min(sum,(x+y)*a);
22                 printf("%lld\n",sum);
23     }
24 }

 

B.Phoenix and Beauty

 

题意:给出n个数,通过进行增加新的数字(数字必须在1-n之间)使得数列任何连续k个数的和相等

思路:通过set进行存储已知数组去重,如果set的长度大于k,则输出-1即可,没有满足条件的数组,如果set长度小于等于k,在k的范围内,输出set所存,不足的数字用1来补齐

题解:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<set>
 6 using namespace std;
 7 int main(){
 8     int n,k,t;
 9     scanf("%d",&t);
10     while(t--){
11         set<int>s;
12         scanf("%d %d",&n,&k);
13         int i;
14         for(i=1;i<=n;i++){
15             int v;
16             scanf("%d",&v);
17             s.insert(v);
18         }
19         if(s.size()>k) cout<<-1<<endl;
20         else
21         {
22             printf("%d\n",k*n);
23             for(i=1;i<=n;i++)
24             {
25                 set<int>::iterator it;
26                 for(it=s.begin();it!=s.end();it++) cout<<*it<< ;
27                 if(s.size()<k){//不够的用1来凑
28                     int j;
29                     for(j=1;j<=k-s.size();j++) cout<<1<< ;
30                 }
31             }
32         }
33     }
34     return 0;
35 }

 

最后就是想补充:这是根据自己的顺手程度从容易到复杂进行整理的,可能每个人感受不一样,但是每个题都有值得去思考的地方,可能通过题训练出思维才是值得的题,并不是简单和难得区分。

最近算法看的太少了,临近期末了在忙着给之前的网课赎罪,还是尽力计划着每一件事情,细分真的能够稳定下来!

05.18.习题训练一

原文:https://www.cnblogs.com/bonel/p/12922134.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!