2020华为杯程序设计竞赛(未完待续)

1.幸福小组
题目描述
俗话说:男女搭配,干活不累。还据说,如果在做一件事情时男生和女生人数相等,学习和工作效率可以达到最佳【瞎说的】。
为了更好地学习计算机专业知识,某个班分为n个学习小组,如果某一个组中男生和女生人数相等,这样的小组称为“幸福小组”。
现在分别给出这n个小组中男生和女生人数,请你编写一个程序统计一共有多少个“幸福小组”。
输入
单组输入。第1行输入一个正整数n,表示学习小组数量。(n<=100)
接下来n行每行包含两个正整数,分别表示每一个学习小组中男生人数和女生人数,两个数字之间用空格隔开。
输出
“幸福小组”的个数。
样例输入
4
1 5
5 1
3 3
4 4
样例输出
2

#include
int main()
{
     
	int n,a[105],b[105],i,k=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d%d",&a[i],&b[i]);
	for(i=0;i<n;i++)
	{
     
		if(a[i]==b[i])
			k++;
	}
	printf("%d\n",k);
	return 0;
}

2.菜鸟驿站
题目描述
HNUCM的TC同学在学校开设了一个收发快递的“菜鸡驿站”,HNUCM一共有n栋宿舍楼,TC需要逐一把快递送到每一栋宿舍楼。
因为刚过完双十一,快递实在是太多太多了,TC每一次只能送一栋宿舍楼,然后再返回驿站取快递来送到下一栋宿舍楼。
现在给出驿站到每一栋宿舍楼的单程时间(单位:分钟,假设来回所需的时间相等),请问TC送完所有快递并返回驿站一共需要多少分钟的时间?
输入
单组输入,每组第1行输入一个正整数n表示宿舍楼的数量(n<=50)。
第2行输入n个正整数分别表示驿站到每一栋宿舍楼所需时间T(T<=109)(单位:分钟)。
输出
送完所有快递并返回到驿站所需的总时间(分钟)。
样例输入
5
3 4 5 6 7
样例输出
50

#include
int main()
{
     
	int n,i;
	long long int a[50],k=0;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%ld",&a[i]);
	for(i=0;i<n;i++)
		k+=a[i];
	printf("%ld\n",2*k);
	return 0;
}

3.TC的火柴
题目描述
今天,TC买了一盒火柴,打算和小yh比拼谁能用有限的火柴得到一个最大数字。火柴拼数字规则是,拼出零到九分别需要6、2、5、5、4、5、6、3、7、6个火柴。
现在给TC a个不同火柴数,求你帮TC计算不同的火柴数a分别能组成的最大数字,如果不能组成数字,输出-1。
输入
第一行输入一个n。
接下来n行,每行一个数a(0<=a<=103)
输出
每行输出一个能组成的最大数字。
样例输入
3
1
2
4
样例输出
-1
1
11
提示
TC说火柴要省着用

#include
int main()
{
     
	int n,i,a[105],k,s=0,j;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(i=0;i<n;i++)
	{
     
		if(a[i]<2)
			printf("%d\n",-1);
		else
		{
     
			for(s=0,j=1;a[i]>=2;)
			{
     
				s*=10;
				k=0;
				if(j==1)
				{
     
					if(a[i]>6)
					{
     
						s+=1;
						k+=2;
					}
				}
				else
				{
     
				    switch(a[i])
				    {
     
				     case 2:
				     case 3:
				     case 4:
				     case 5:s+=1;k+=2;break;
				     case 6:
				     case 7:s+=0,k+=2;break;
					}
				}
				a[i]-=k;
				j++;
			}
			printf("%d\n",s);
		}
	}
	return 0;
}

4.n盏灯
题目描述
有n盏灯,序号为1到n。在初始状态下,所有的开关都是关的。
有n个开关控制这n盏灯,第i个开关控制第i盏灯。
现在从1开始计数,每遇到一个素数就把该素数对应的倍数序号的开关朝相反的方向拨一下,一直到最后一个小于等于n的素数为止。请统计最后有多少盏灯是开的?
输入
多组输入,每组输入一个n(2<=n<=106)。
输出
每组数据,输出开的灯的盏数
样例输入
10
样例输出
7

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn=1000000+5;
bool prime[maxn];
int sum[maxn];
bool judge(int n){
     
    if(n==1)return false;
    if(n<=3)return true;
    if(n%2==0||n%3==0)return false;
    for(int i=5;i<=sqrt(n);i+=6){
     
        if(n%i==0||n%(i+2)==0)return false;
    }
    return true;
}
void init(){
     
    for(int i=1;i<=maxn;i++)
        if(judge(i))prime[i]=true;
}
int main()
{
     
    int n;
    init();
    while(cin>>n){
     
        int ans=0;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=n;i++){
     
            if(!prime[i])continue;
            for(int j=i;j<=n;j+=i)sum[j]++;
        }
        for(int i=1;i<=n;i++)
            if(sum[i]%2==1)ans++;
        cout<<ans<<endl;
    }
    return 0;
}

5.电子手表
题目描述
一个电子手表,可以显示时分秒,且每一个都采用两位阿拉伯数字。
现在输入一个开始时间和一个结束时间,例如00:00:00和10:20:59。
请统计从开始时间到结束时间(包括开始时间和结束时间)之间在屏幕上显示0的个数。
注意:每秒钟为1个计数单位,例如00:00:00到00:00:01一共显示了11个0。
输入保证开始时间和结束时间的合法性,即0<=小时<=23,0<=分钟<=59,0<=秒钟<=59。
输入
开始时间和结束时间,格式均为HH:MM:SS(HH表示小时,MM表示分钟,SS表示秒钟)。
输出
从开始时间到结束时间之间在屏幕上显示0的个数(包括开始时间和结束时间)。
样例输入
00:00:00
00:00:10
样例输出
56

#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
     
    int a1,b1,c1,a2,b2,c2,s=0;
    scanf("%d:%d:%d",&a1,&b1,&c1);
    scanf("%d:%d:%d",&a2,&b2,&c2);
    for(;a1<=a2;a1++)
        for(;b1<=60;b1++)
        {
     
            if(b1==60)
            {
     
                b1=0;
                break;
            }
            for(;c1<=60;c1++)
            {
     
                if(c1==60)
                {
     
                    c1=0;
                    break;
                }
                if(a1==0)s+=2;
                else if(a1>0&&a1<=10||a1==20)s++;
                if(b1==0)s+=2;
                else if(b1>0&&b1<=10||b1%10==0)s++;
                if(c1==0)s+=2;
                else if(c1>0&&c1<=10||c1%10==0)s++;
                if(a1==a2&&b1==b2&&c1==c2)
                {
     
                    cout<<s<<endl;
                    break;
                }
            }
        }
}

6.TC的steam账号
题目描述
一共有n个学弟(编号为1-n)向TC借steam的账号,不过TC休闲时也会玩下steam游戏,所以TC准备只借给其中的k个人。
TC按照他们的OJ刷题数量给每个人赋予了一个初始权值W[i]。然后将初始权值从大到小进行排序,每人就有了一个序号Di 。
按照这个序号对10取模的值将这些人分为10类.(也就是说定义每个人的类别序号C[i]的值为((D[i]-1) mod 10 +1)显然类别序号的取值为1-10。第i类的人将会额外得到E[i]的权值。
你需要做的就是求出加上额外权值以后,最终的权值最大的k个人,并输出他们的编号。在排序中,如果两人的W[i]相同,编号小的优先。
输入
第一行输入用空格隔开的两个整数,分别是n和k。
第二行给出了10个正整数,分别是E[1]到E[10] 。
第三行给出了n个正整数,第i个数表示编号为i的人的权值W[i] 。
题目保证:1≤k≤n≤32768,1≤W[i],E[i]≤1000。
输出
只需输出一行用空格隔开的k个整数,分别表示最终W[i]从高到低k个人的编号。
样例输入
10 10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
样例输出
10 9 8 7 6 5 4 3 2 1

#include 
#include 
#include 
#include 
#include 
using namespace std;
struct people{
     
    int id,w;
}p[50000];
int e[11];
bool cmp(people &a,people &b){
     
    if(a.w!=b.w)return a.w>b.w;
    else return a.id<b.id;
}//重点
int main()
{
     
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=1;i<=10;i++)cin>>e[i];
    for(int i=1;i<=n;i++)cin>>p[i].w,p[i].id=i;
    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++)p[i].w+=e[(i-1)%10+1];
    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=k;i++)cout<<p[i].id<<" ";
    cout<<endl;
    return 0;
}

7.万圣节
题目描述
一年一度的万圣节马上就要到了,弓箭手小明和剑士小刚约好一起去猎杀幽灵,一共有n个幽灵,第i只幽灵会掉落ai件弓箭手装备,bi个剑士装备。
小明的收获总和是他猎杀的幽灵的ai值之和。小刚的收获总和是他猎杀的幽灵的bi值之和。小明小刚轮流行动,小明先手。两人都能保证一击必杀。
小明和小刚的目的尽可能让自己收获比对方高。你需要求出两人都使用最优策略的情况下,输出他们的收获差。我们保证所有幽灵掉落装备总价值不同。
输入
第一行输入一个正整数n表示幽灵个数
第二行输入n个数a1,a2,a3…an
第三行输入n个数b1,b2,b3…bn。
题目保证1≤n≤105, -109≤ai,bi≤109。
输出
两人都使用最优策略的情况下,他们的收获的差值(取绝对值)
样例输入
3
8 7 6
5 4 2
样例输出
10
提示
小明选择1号和3号幽灵,得到了14件装备,小刚只能选择2号幽灵得到4件装备,差值为10.


8.最少颜色
题目描述
给定无向连通图G和m种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。
如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。
求解目标颜色出现最少次数的图的m着色问题。
输入一张地图(n个顶点),m种颜色(1-m),输入颜色k(1-m),要求使用m种颜色对地图进行着色,并且颜色k出现的次数最少。
输入
第1行n个顶点(编号1-n),e条边,m种颜色(编号1-m),颜色k
接下来e行,表示两个顶点之间存在的边
题目保证:1<=n<=50,n-1<=e<=500 ,1<=k<=m<=10,不存在自环与重边 。
输出
输出k出现的最少次数。
如果对于给定条件,图的m着色问题无解则输出-1
样例输入
4 3 3 1
2 4
1 2
1 3
样例输出
0


9.解密
题目描述
湖南中医药大学有含浦、东塘 2 个校区,学校办学历史悠久,前身为 1934 年的湖南国医专科学校,1953年创办湖南中医进修学校,1960 年创建普通高等本科院校——湖南中医学院,1979 年成为全国首批取得
中医类研究生学历教育资格的院校,1990 年原湖南科技大学成建制并入湖南中医学院,2002 年与湖南省中医药研究院合并,2006 年经教育部批准更名为湖南中医药大学,2012 年进入湖南省一本招生序列。
目前,学校与湖南省中医药研究院实行校院合一的管理体制。学校学科门类齐全、中医药特色鲜明。学校设有 18 个学院、24 个本科专业,涵盖医、理、工、管、文等 5 大学科门类。中医诊断学在本学科研究领域居国内领先水平。
小 F 居住在含浦校区,他想和东塘校区的同学小 L 聊天,为了保证沟通安全,他发明了一种奇特的加密方式,这种加密方式是这样的:对于一个 01 串,小 F 会构造另一个 01 串,使得原串是在新串中没有出现过得最短的串。
现在小 F 已经加密好了一个串,但他发现他的加密方式有些 bug,导致没出现过的最短的串不止一个,他感到非常懊恼,现在他希望计算出没出现过的最短的串的长度。
输入
单组数据。
一行一个 01 串,字符串串长小于等于 105。
输出
一行一个正整数,表示没有出现过的最短串的长度。
样例输入
100010110011101
样例输出
4


10.TC的门牌号
题目描述
众所周知,TC住在比特楼,由于他不想被人打扰,于是对楼层的门牌号施加了x魔法。
现在,比特楼的门牌号排列规则如下: 门牌号[1,2]位于第一层, 门牌号[3,x+2]位于第二层, 门牌号[x+3,2x+2]位于第三层, 依次类推…
现在,TC会改变x和自己的门牌编号num,需要你来找出TC的楼层。
输入
第一行一个整数T(1<=T<=1000)表示测试数据组数,接下来T组数据。
每组数据包含两个整数num,x(1<=num,x<=10000),表示TC的门牌号和x魔法。
输出
对于每组数据,输出一个整数表示TC所在楼层
样例输入
2
5 3
10 3
样例输出
2
4
(数学理解方法)

#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
     
    int t;
    cin>>t;
    while(t--){
     
        int num,x;
        cin>>num>>x;
        if(num==1||num==2)
        {
     
            cout<<1<<endl;
            continue;
        }
        num-=2;
        int ans=num/x;
        if(num%x!=0)ans++;
        cout<<ans+1<<endl;
    }
    return 0;
}

(简便做法)

#include 
#include 
#include 
#include 
#include 
using namespace std;
int main()
{
     
    int n,x,num,i,h;
    cin>>n;
    while(n--)
    {
     
        cin>>num>>x;
        h=1;
        for(i=1;;i++)
        {
     
            if(num==1||num==2)break;
            if((i-1)*x+3<=num)
            h++;
            else break;
        }
        cout<<h<<endl;
    }
}

有些题目暂时不会 但是我一定会把它们解决掉的

你可能感兴趣的:(程序设计,算法,c++)