zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

       
       
  • 相关阅读:
    Linux编程 22 shell编程(输出和输入重定向,管道,数学运算命令,退出脚本状态码)
    mysql 开发进阶篇系列 46 物理备份与恢复( xtrabackup的 选项说明,增加备份用户,完全备份案例)
    mysql 开发进阶篇系列 45 物理备份与恢复(xtrabackup 安装,用户权限,配置)
    mysql 开发进阶篇系列 44 物理备份与恢复( 热备份xtrabackup 工具介绍)
    Linux编程 21 shell编程(环境变量,用户变量,命令替换)
    Linux编程 20 shell编程(shell脚本创建,echo显示信息)
    mysql 开发进阶篇系列 43 逻辑备份与恢复(mysqldump 的基于时间和位置的不完全恢复)
    Linux编程 19 编辑器(vim 用法)
    (网页)angularjs中的interval定时执行功能(转)
    (网页)在SQL Server中为什么不建议使用Not In子查询(转)
  • 原文地址:https://www.cnblogs.com/liyongqi/p/12925248.html
Copyright © 2011-2022 走看看