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 }
最后就是想补充:这是根据自己的顺手程度从容易到复杂进行整理的,可能每个人感受不一样,但是每个题都有值得去思考的地方,可能通过题训练出思维才是值得的题,并不是简单和难得区分。
最近算法看的太少了,临近期末了在忙着给之前的网课赎罪,还是尽力计划着每一件事情,细分真的能够稳定下来!
原文:https://www.cnblogs.com/bonel/p/12922134.html