• 2020-05-18 — 习题训练一


    A Phoenix and Balance

    题意:给定n个数,从1-n分别是2^1,2^2……2^n,然后把他们分成个数相同的2部分,问如何分才能使得a-b的绝对值最小

    题解:  根据各个值可以发现2^n一定比前面的所有数字相加都大,就是2^n>2^n-1+2^n-2……2^1,所以把最大值给一边,然后从大到小把n/2的值给另外一边就行

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int t,n,sum1,sum2;
    	cin>>t;
    	while(t--){
    		cin>>n;
    		sum1=0;
    		sum2=pow(2,n);
    		for(int i=n/2;i<=n-1;i++){
    			sum1+=pow(2,i);
    		}
    		for(int i=1;i<n/2;i++){
    			sum2+=pow(2,i);
    		}
    		cout<<abs(sum1-sum2)<<endl;
    	}
    	return 0;
    }
    

     BPhoenix and Beauty

    题意:给定n个数,要求他们按顺序k个数相加都要相等,可以在中间添数字,如果没有办法使他们相等则输出-1(a1,a2,a3,a4,如果k=2的话就是a1+a2=a2+a3=a3+a4=a4)

    题解:找周期吧,设他们有多少个不同的数为k1,如果k1>k,那么无论怎么加数字都不能成功输出-1,否则可以输出n个周期(比如n=4 k=3,就可以1 2 3 1 2 3 1 2 3 1 2 3)

    代码:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    int a[105],vis[105],c[105],cn;
    int main() {
    	int t,i,b,n,k,cnt,j;
    	scanf("%d",&t);
    	while(t--) {
    		scanf("%d%d",&n,&k);
    		for(i=1; i<=100; i++)vis[i]=0;
    		for(i=1; i<=n; i++)scanf("%d",&a[i]),vis[a[i]]=1;
    		cnt=0;
    		for(i=1; i<=100; i++)			if(vis[i])cnt++;
    		if(cnt>k) {
    			printf("-1
    ");
    			continue;
    		}
    		if(cnt<k)			for(i=1; i<=100; i++)				if(!vis[i]) {
    					vis[i]=1,cnt++;
    					if(cnt==k)break;
    				}
    		cn=0;
    		for(i=1; i<=100; i++)			if(vis[i])c[++cn]=i;
    		printf("%d
    ",n*k);
    		for(i=1; i<=n; i++) 			for(j=1; j<=k; j++)printf("%d ",c[j]);
    		printf("
    ");
    	}
    	return 0;
    }
    

    C - Road To Zero

     题意:给你x和y,你有2个方法一个是他们每个都减1花费a元或者使其中一个减1花费b元,问怎样使得花费最低。

    题解:就是找出花费最低的一个方法,当x和y都不是0时,可以通过第一种方法把其中最小的变为0,然后再加上剩下的值,或者全部使用第二个方法,比较他们2个哪个方案最小(如果第一种方法小于第二种时,不能一直使用第二种,因为其中一个数为0时不能再一起-1 - ,-)

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main(){
    	int t;
    	ll x,y;
    	ll a,b;
    	ll sum1,sum2,sum3;
    	cin>>t;
    	while(t--){
    		cin>>x>>y;
    		cin>>a>>b;
    	//	if(b<=a){
    		//	sum1=max(x,y)*b;
    	//		cout<<sum1<<endl;
    	//	}
    		//else{一个数到0不能2个一起减 
    		sum2=min(x,y)*b+(max(x,y)-min(x,y))*a;
    		sum3=(x+y)*a;
    		cout<<min(sum2,sum3)<<endl;	
    	//	}
    	}
    	return 0;
    } 
    

      

    D - Binary Period

     题意:跟第二题类似,只不过只能01串,然后添加数字使得他们有周期,最后的序列长度要小于等于2*s

    题解:如果序列只有相同的数,那肯定本身就有周期了是1,如果不相同,就一直0101排列就好(比如010,s的长度是3那就可以输出一个长度6的序列要有周期,直接输出010101就可)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int t,l,flag;
    	string a;
    	cin>>t;
    	while(t--){
    		flag=0;
    		cin>>a;
    		l=a.size();
    		for(int i=0;i<a.size()-1;i++){
    			if(a[i]!=a[i+1]){
    				flag=1;//有2个字符 
    				break;
    			}
    		}
    		if(flag==0){
    			cout<<a<<endl;
    		}
    		else{
    			for(int i=0;i<l;i++){
    				cout<<"1"<<"0";
    			}
    			cout<<endl;
    		}
    	}
    	return 0;
    } 
    

      

    E - Nastya and Rice

     题意:

    给你一个一袋米重量的范围和其中每一粒米的重量范围,问n个这些米是否在这个范围内

    题解:

    就是如果最大的重量*n<一袋米的重量或者最小的重量*n>一袋米的重量就不符合

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int t;
    	int n,a,b,c,d;
    	int flag;
    	cin>>t;
    	while(t--){
    		flag=0;
    		cin>>n>>a>>b>>c>>d;
    		if(n*(a-b)>c+d){
    			flag=1;
    		}
    		if(n*(a+b)<c-d){
    			flag=1;
    		}
    		if(flag==1){
    			cout<<"No"<<endl;
    		}
    		else{
    			cout<<"Yes"<<endl;
    		}
    	}
    	return 0;
    } 
    

      

    F - Nastya and Door

     题意:

    给定一个序列,如果其中一个数大于左边且大于右边就能把他们分开(an>an-1&&an>an+1)然后再取一个k为从这个序列取k的长度,问哪一个取法能把他们分得最开

    题解:

    一开始看半天没看懂。。。然后其实可以用前缀和做,把i-1中有峰值记录下来,然后根据给定的长度算出a[i+k]-a[k],看哪边的峰值最多输出就好,题目有个坑,如果i和i+k是峰值,那a[i+k]-a[i]=0的,就是本身使不能算,后面一个值才能+1

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int f[200005];
    int main()
    {
        int t;
        scanf("%d",&t);
        int n,k;
        int fr1,fr2;
        int fr3;
        int ans;
        int l=1;
        while(t--)
        {
            memset(f,0,sizeof(f));
            scanf("%d%d",&n,&k);
            scanf("%d%d",&fr1,&fr2);
            for(int i=3;i<=n;i++)
            {
                scanf("%d",&fr3);
                if(fr2>fr1&&fr2>fr3) f[i]=f[i-1]+1;
                else
                {
                    f[i]=f[i-1];
                }
                fr1=fr2;
                fr2=fr3;
            }
            ans=0;
            l=1;
            for(int i=k;i<=n;i++)
            {
                if(ans<f[i]-f[i-k+2])
                {
                    ans=f[i]-f[i-k+2];
                    l=i-k+1;
                }
            }
            printf("%d %d
    ",ans+1,l);
        }
        return 0;
    }
    

      

       
       
  • 相关阅读:
    WPF进阶技巧和实战03-控件(3-文本控件及列表控件)
    WPF进阶技巧和实战08-依赖属性与绑定03
    WPF进阶技巧和实战08-依赖属性与绑定02
    WPF进阶技巧和实战08-依赖属性与绑定01
    WPF进阶技巧和实战07--自定义元素02
    WPF进阶技巧和实战07--自定义元素01
    Codeforces Round #730 Div. 2
    Codeforces Round #701 Div. 2
    Codeforces Round #700 Div. 2
    Codeforces Round #699 Div. 2
  • 原文地址:https://www.cnblogs.com/liyongqi/p/12925248.html
Copyright © 2020-2023  润新知