武汉工程大学2020GPLT选拔赛(上)

比赛链接

A L1-1 I LOVE WIT

模拟,每个字母单独一行,前面的空格按规律输出。可以直接输出,也可以模拟过程

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s="I LOVE WIT";
    for(int i=0;i<s.size();++i)
    {
        for(int j=1;j<=i;++j)
        {
            cout<<" ";
        }
        cout<<s[i]<<endl;
    }
    return 0;
}

B L1-2 单位换算

根据题目总结公式:
sum=n122.54*10
注意如果不是整数就保留一位小数,否则不留小数

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    double sum=1.0*n*12*2.54*10;
    int w=sum;
    if(fabs(sum-w)<=0.001)
        printf("%d",w);
	else
	{
        printf("%.1lf",sum);
    }
    return 0;
}

C L1-3 Pokémon

根据题目要求输出运算
cv对应着相应的概率,再看f等于0或1,乘以对应的概率,直接运算就可以。
注意读入与输出时都有百分号,特别处理一下

#include<bits/stdc++.h>
using namespace std;
double a[7];
int main()
{
	   int cv,f;
    for(int i=0;i<=6;++i)
	{
        cin>>a[i];
        char ch=getchar();
    }
 
    cin>>cv>>f;
    if(f==1)
	{
        a[cv]*=0.01;
    }
	else
	{
        a[cv]*=0.99;
    }
    printf("%.2lf",a[cv]);
    cout<<"%";
    return 0;
}

D L1-4 颠倒阴阳

我们先分析分析有多少步骤
首先当然是将n转化成2进制形式
然后取反
然后高低位翻转
最后转发成十进制

中间两步我们可以合在一起,因为我们用数组来存二进制,取反后存的时候可以直接倒着存,就相当于翻转了。
取反时不要讲多余部分取反,直接判断n是否已除尽
详细看代码吧

#include<bits/stdc++.h>
using namespace std;
int  a[32];
typedef long long ll;
 
int main(){
    ll n;
    cin>>n;
 	for(int i=32;i>=1;i--)
 	{	
	 	int w=n%2;
	 	if(n)
 		a[i]=!w;
	 	n>>=1;
 
	}

	ll sum=0;
	for(int i=1;i<=32;i++)
	{
		if(a[i]!=0)
		sum+=pow(2,i-1);
	}
	cout<<sum; 
}

E L1-5 演唱会

题目好理解
我们读入是将时分秒分别存入hh,mm,ss中,然后分别加上1,22,33,注意进位,从ss开始每满60进一位,最后比较时分别于演唱会开始与结束时间比较,从小时开始比到秒
(这么做还要进位太麻烦了吧)
其实直接将所有时间都转化成秒,直接对比多方便

怎么方便怎么做

#include<bits/stdc++.h>
using namespace std;
int main(){
    int hh,mm,ss;
    int sum;
    char ch;
    cin>>hh>>ch>>mm>>ch>>ss;
    sum=hh*3600+mm*60+ss;
    sum+=3600+22*60+33;
    int beg=19*3600,ed=21*3600;
    if(sum<beg)
	{
        cout<<"arrive on time";
    }
	else if(sum<ed)
	{
        cout<<"arrive late";
    }
	else
	{
        cout<<"too late";
    }
    return 0;
}

F L1-6 分鸽子

(吃鸽子!!鸽子保护协会表示抗议)
终于有个涉及算法的题了
二分问题
我们要知道正确答案是在区域[l,r]之间的,一开始l=1,r=1e9+2,然后不断缩小l与r的范围
我们先枚举一个mid作为答案,然后判断mid是否符合条件,如果符合说明可能存在更佳的答案,就把左边界更新(扩大)
如果不符合说明当前答案太大了,就把右边界缩小
这个条件怎么判断呢?
我一开始是先看mid*m与sum(a[i])也就是需要的鸽子肉与有的鸽子肉比较,如果大于已有mid肯定多了
如果小于就看mid是不是比单个鸽子肉小,因为不能混搭
我感觉这样做问题不大,结果过了一半,懵了
然后换了一个判断方法,直接看每个鸽子以当前mid标准能分成几份,如果份数大于人数,即符合要求,反之不符合
具体看代码吧

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+3;
int a[maxn];
  int n,m;
//inline bool check(int mid)
//{
//	if(mid*m>summ)return 0;
//	for(int i=1;i<=n;i++)
//	if(mid>a[i])return 0;
//	return 1;
//}
bool check(int x){
      long long sum=0;
    for(int i=1;i<=n;++i){
        res+=(a[i]/x);
    }
    return res>=m;
}
int main()
{
	
	  cin>>n>>m;
	  for(int i=1;i<=n;i++)
	  {
	  	cin>>a[i];
	  	sum+=a[i];
	  }
	  int l=1;
	  int r=1e9+2;
	  int mid;
	  while(l<=r)
	{
	  	mid=(l+r)>>1;
//	  	printf("mid=%d %d %d\n",mid,l,r);
	  	if(check(mid))
	  	{
	  			l=mid+1;
		}
		else 
		{
				r=mid-1;
		}
	}
	cout<<r;
	return 0;
	  
}
posted @ 2020-05-09 16:31  回归梦想  阅读(116)  评论(0编辑  收藏  举报