第六届“图灵杯”NEUQ-ACM程序设计人赛真题重现


前言

提示:代码以AC,如果没有会在代码前进行说明


系列文章目录

第四届“图灵杯”NEUQ-ACM程序设计人赛真题重现

第五届“图灵杯”NEUQ-ACM程序设计个人赛真题重现

第六届“图灵杯”NEUQ-ACM程序设计人赛真题重现

第七届“图灵杯”NEUQ-ACM程序设计个人赛真题重现


一、秋季特惠

题目描述

秋季特惠就要来了,FinFin克制不住自己想买游戏的手了。现在FinFin想要买w件游戏,打折后,第一件需要花费k元,第二件需要2k元,依此类推。换句话说,第i件游戏需要花费ik元。现在小果果有n元,请问他至少还需要从他朋友手中借多少钱才能买到这w件游戏?

输入描述
第一行输入一个整数T,代表测试数据组数.0<T<1000 接下来T行每行输入三个整数k,n,w(1≤k≤1000,1≤w≤1000,1≤n≤10^9),分别代表第一件游戏的价格,FinFin拥有的钱的数量和他想买的游戏数量。

输出描述
对于每组测试数据,输出FinFin需要从朋友手中借钱的数量。如果FinFin的钱足够则输出0。

样例输入
2
3 17 4
1 5 6
样例输出
13
16

AC代码如下:


#include <iostream>
#include <cmath>
using namespace std;
long long int k,n,w;
long long int sum;
int main ()
{
	int t;
	cin>>t;
	while (t--)
	{
		cin>>k>>n>>w;
		sum=(w*(w+1)*k/2);
		if (sum<=n)
		{
			cout<<0<<endl;
		}else {
			cout<<sum-n<<endl;
		}
	}
	
	return 0;
	
}

二、找工作

题目描述

Gold终于在自己秃顶之前找到了女朋友,但是无奈谈恋爱太花钱,Gold决定找份兼职挣钱。Gold打听到SSR(Small Soup River)School最近正在招补习班老师,他决定去应聘,SSR School的Boss出了一道多项式求导的题来考Gold,Gold因为最近天天忙着谈恋爱,什么都忘完了,但是他很需要这份工作,你能帮帮他吗?

输入描述
一个整数T(1≤T≤100),表示测试数据的组数。 之后2*T行: 第一行一个正整数n(0≤n≤100),表示该多项式的最高次数。 第二行n+1个整数,分别表示xn到x0各项的系数。(-100≤xi≤100).

输出描述
输出共有T行。 由高次到低次,输出每一项的系数。忽略前导零。

样例输入
2
3
1 2 3 4
3
0 0 2 1
样例输出
3 4 3
2

分析

1 . 如果最高次数是0,则输出0;
2 . 如果求导后系数全部是0 则输出0;

AC代码如下:


#include <iostream>
#include <cmath>
using namespace std;
long long int k,n,w;
long long int sum;
int main ()
{
	int t;
	cin>>t;
	while (t--)
	{
		int k;
		cin>>k;
		bool ok=false;
		bool okk=false;
		int map[300];
		for (int i=0;i<=k;i++)
		{
			cin>>map[i];
		}
		
		for (int i=0;i<=k;i++)
		{
			map[i]=map[i]*(k-i);
			if (map[i]!=0)
			{
				okk=true;
			}
		}
		
		if (k==0||okk==false)
		{
			cout<<0<<endl;
		}else{
			for (int i=0;i<k;i++)
			{
				if (ok==true)
				{
					if (i==k-1)
					{
						cout<<map[i];
					}else{
						cout<<map[i]<<" ";
					}
				}else if (map[i]!=0&&ok==false)
				{
					ok=true;
					if (i==k-1)
					{
						cout<<map[i];
					}else{
						cout<<map[i]<<" ";
					}
				}
			}
			cout<<endl;
		}
		
	}
	
	return 0;
	
}

三、购物计划

题目描述

ELATIS去了一家名为GCD的超市,ELATIS需要购买n个物品,物品的售价为从1到n,编号也为1到n,这家超市的经营方式有点不太一样,ELATIS每次可以从这n个物品中选一样物品,需要支付的价格为还没被购买的所有物品的价格的最大公因数(包括即将购买的商品)。 假设ELATIS需要买4件物品,那么他可以按1,3,2,4的顺序购买。第一次购买1号物品,支付gcd(1,2,3,4)=1元,第二次购买3号物品,支付gcd(2,3,4)=1元,第三次购买2号物品,支付gcd(2,4)=2元,第四次购买4号产品支付gcd(4)=4元。则总共需要支付8元。(gcd(a,b)表示a和b的最大公因数) ELATIS想知道自己买下这n个物品所需要的最小花费,并且按价格从高到底顺序输出购买每件物品所支付的价格

输入描述
一个正整数T,表示测试的组数(1≤T≤100) 一个正整数n (1≤n≤1000)

输出描述
对于每一组: 输出共两行。 第一行一个正整数表示最小花费。 第二行个正整数表示购买每个物品的实际价格(降序)。

样例输入
1
1
样例输出
1
1

分析

1 . 每件物品需要支付的价格为还没被购买的所有物品的价格的最大公因数(包括即将购买的商品)
2.当还没被购买的所有物品的价格中有两个质数(或者有1)时那么最大公因数就是1 啦
3 只要最后购买第一件商品,那么购买n件商品只需支付n元,
所以这样的超市在哪,请务必告诉我!!!

AC代码如下:

#include <iostream>
#include <cmath>
using namespace std;
int main ()
{
	int t;
	cin>>t;
	while (t--)
	{
		int n;
		cin>>n;
		cout<<n<<endl;
		cout<<1;
		for (int i=1;i<n;i++)
		{
			cout<<" "<<1;
		}
		cout<<endl;
	}
	return 0;
	
	
}

四、蟹黄堡的配方

题目描述

痞老板经过孜孜不倦的研究和日以继日的跟踪,终于发现了蟹老板蟹黄堡的配方的秘密。蟹黄堡的调料有两种,它们的味道可以由两个字符串表示,如:“az"和"by”,意思是先将a调料和b调料混合,再将z调料和y调料混合,最终就得到了味道为"ay"的蟹黄堡。 严谨地说,就是从给定长度为n的字符串a和b构造一个新的长度为n的字符串s,使得对于所有的1≤i≤n,si=min{ai,bi},即从a、b两个字符串第i个位置中选取字典序靠前的字符作为字符串s第i位的字符,字典序的定义如下: 百度百科: 在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 现在痞老板得到了其中一个调料字符串,但他并不知道另一个调料字符串是什么,他从海绵宝宝那里偷来了一个蟹黄堡,希望你能帮他找到另一个调料字符串的配方。如果发现无法得到另一个调味料字符串,说明痞老板把配方搞错了,请你输出一个整数 -1 来告诉他。因为痞老板比较穷,而调料的价格随着字典序的增加而增加,所以请你在所有的可能字符串中选择字典序最靠前的输出。

输入描述
第一行输入一个整数T(1≤T≤100),表示数据的组数。 接下来T组输入,每组输入3行。 每组第一行一个整数n,表示三种字符串的共同长度。 每组第二行一个字符串a,表示蟹老板的第一种调料字符串。 每组第三行一个字符串s,表示成品蟹黄堡字符串。 题目保证a、b、s字符串都由小写英文字母组成,长度都为n ,(1≤n≤100000)

输出描述
输出T组数据,每组一行一个字符串,表示蟹老板的第二种调料字符串,或者一个整数 -1 表示无法获知第二个调料字符串。

样例输入
2
2
ab
ba
1
a
a
样例输出
-1
a

分析

简单的字符出比较

AC代码如下:

#include <iostream>
#include <cstring>
using namespace std;
int t;
char a[100005],s[100005],b[100005];

int main ()
{
	cin>>t;
	while (t--)
	{
		int n;
		cin>>n;
		cin>>a;
		cin>>s;
		bool ok=false;
		for (int i=0;i<n;i++)
		{
			if (s[i]<=a[i])
			{
				b[i]=s[i];
			}
			if (s[i]>a[i])
			{
				cout<<"-1"<<endl;
				ok=true;
				break;
			}
		}
		if (ok==false)
		{
			for (int i=0;i<n;i++)
			{
				cout<<b[i];
			}
			cout<<endl;
		}
		
	}
	return 0;
	
}

五、大圈圈

题目描述

Antler是一个设计师,她很喜欢画圈圈。有一天,农场主邀请Antler去设计一块新的农场,因为Antler很喜欢画圈圈,所以她打算用圈圈来设计这个农场(保证任意两个圈圈(圆)有且仅有两个交点),农场主支付了Antler画n个圈的费用,农场主想知道这n个圈最多可以把农场分为多少部分(农场面积无限大)。 由于答案也许会非常大,计算机有可能存不下,所以我们要求答案对 1000000007 取模。

输入描述
一个整数T,表示测试数据的组数。 T个整数 n(1≤n≤10000)。

输出描述
每行一个整数,表示农场最多能被划分成多少部分。

样例输入
3
1
2
3
样例输出
2
4
8

分析

当n-1个圆时,区域数为f(n-1).那么第n个圆就必须与前n-1个圆相交,则第n个圆被分为2(n-1)段线段,于是增加了2(n-1)个区域。

AC代码如下:

#include <iostream>
#include <cstring>
using namespace std;
const int mod=1000000007;
int t;
int map[10005];
int main ()
{
	cin>>t;
	map[1]=2;
	map[2]=4;
	map[3]=8;
	for (int i=4;i<=10001;i++)
	{
		map[i]=(map[i-1]+(i-1)*2)%mod;
	}
	while (t--)
	{
		int a;
		cin>>a;
		cout<<map[a]<<endl;
	}
	return 0;
}

六、恶龙与勇者

题目描述

n条恶龙闯入了王国的领土,为了拯救王国的危机,国王任命你前往冒险者工会雇佣勇者前去讨伐恶龙。每条恶龙的战斗力为ai。每个勇者的战斗力为bi,雇佣他的花费为ci。只有当勇者的战斗力大于等于恶龙的战斗力时,勇者才能击败恶龙。因为勇者都是骄傲的,所以勇者们拒绝互相组队(即每个勇者只能独自一人去讨伐恶龙)。勇者们都具有凝聚空气中魔力的能力,因此可以无限次出战。王国需要金币去灾后重建,需要你计算打败所有恶龙的最小花费。

输入描述
第一行输入一个整数T,表示数据的组数。1≤T≤10。 第一行输入n,m,表示龙的数量和冒险者的数量。0<n,m≤10000。 接下来n行,每行一个数字ai表示龙的战斗力。 接下来m行,每行分别为bi和ci,表示冒险者的战斗力和雇佣他的花费。0<=ai,bi,ci≤100000。

输出描述
如果能击退恶龙们,请输出最小的花费,如果不能,请输出"Kingdom fall"

样例输入
2
1 1
6
10 3
3 2
10
14
15
9 10
6 7

分析

注意一位勇士只能挑战一只恶龙,挑战第二只恶龙就得换人了

AC代码如下:

#include <iostream>
#include <algorithm> 
#include <cstring>
#include<limits.h>
using namespace std;
int t;
int n,m;

struct node {
	int HP;
	int money;
};
bool cmp(node x,node y)
{
	if (x.HP==y.HP)
	{
		return x.money<y.money;
	}else {
		return x.HP>y.HP;
	}
}
int main ()
{
	cin>>t;
	
	while (t--)
	{
		cin>>n>>m;
		int dragon[n+1];
		node hero[m+1];
		 
		int sum=0;
		for (int i=0;i<n;i++)
		{
			cin>>dragon[i];
			
		}
		for (int i=0;i<m;i++)
		{
			cin>>hero[i].HP>>hero[i].money;
		}
		sort (dragon,dragon+n);
		sort (hero,hero+m,cmp);
		
		if (hero[0].HP<dragon[n-1])
		{
			cout<<"Kingdom fall"<<endl;
			
		}else {
			int MIN=100010;
			for (int i=0;i<n;i++)
			{
				for (int j=0;j<m;j++)
				{
					if (dragon[i]>hero[j].HP)
					{
						break;
					}
					if (MIN>hero[j].money)
					{
						MIN=hero[j].money;
					}
				}
				sum+=MIN;
				MIN=100010;
			}
			cout<<sum<<endl;
		}
		
	}
	return 0;
}

七、搭积木

题目描述

年总最近投资了一家幼儿园,但是他觉得幼儿园的活动太单调了,他决定搞点大新闻。思前想后,他打算举办搭积木大赛。 比赛要求是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi。在搭建开始之前, 没有任何积木(可以看成n块高度为0的积木)。接下来每次操作,小朋友们可以选择一段连续区间[L, R],然后将第L块到第 R块之间(含第L块和第R块)所有积木的高度分别增加1。 妍妍是个聪明的小朋友,她很快想出了建造大厦的最佳策略,使得建造所需的操作次数最少。但她不是一个勤于动手的孩子,所以想请她最好的朋友贞贞帮忙实现这个策略,并求出最少的操作次数。

输入描述
第一行一个整数n,(1≤n≤5*10^5),表示大厦的宽度。 之后n个整数hi(1≤hi≤10^9)。

输出描述
所需要的最少操作数。

样例输入
6
4 3 2 5 3 5
样例输出
9

分析

一次只能把积木的高度增加1,所以把积木高度画成折线图,在某个单调不下降(不上升)的区间需要的操作数就等于波峰的值,
所以一共需要的操作的数就是波峰的和,而两个波峰之间的波谷被记算了两次所以再减去波谷的值就好

AC代码如下:

#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
int n;
long long int map[500005];
long long int ans=0;
long long int sum=0;

int main ()
{
	cin>>n;
	int ok=1;
	for (int i=0;i<n;i++)
	{
		cin>>map[i];
		if (i==1)
		{
			if (map[1]>map[0])
			{
				ok=1;
		   	}
			if (map[1]<map[0])
			{
				ok=-1;
				sum+=map[0];
			}
		}
		if (i==0)
		{
			ans=map[i];
		}else {
			if (map[i]>map[i-1]&&ok==1)
			{
				ans=map[i];
			}else if (map[i]<map[i-1]&&ok==1)
			{
				
				sum+=ans;
				ans=map[i];
				ok=-1;
				
			}else if ((map[i]<map[i-1])&&ok==-1)
			{
				ans=map[i];
			}else if (map[i]>map[i-1]&&ok==-1)
			{
				
				sum-=ans;
				ans=map[i];
				ok=1;
			}
			if (i==n-1)
			{
				if (ok==1)
				{
					sum+=map[i];
				}
			}
		}
	}
	
	cout<<sum<<endl;
	return 0;
}

八、一条数学题

题目描述!

程序猿小骏的孩子小小骏在小汤河中学就读。这天数学课的王老师讲到了等差数列的概念:等差数列是一个能够表示成a, a+b, a+2b, …, a+nb (n=0,1,2,…) 的数列,其中a,为整数,且b为正整数。 放学后,王老师布置了一条数学题:让小小骏在所有双平方数中,找到所有长度为n的等差数列。(双平方数指的是所有能表示成p2+q2的数,其中p,q都为整数。)这下可把小小骏弄得挠头不已。他拿去问小骏,可是小骏的数学是体育老师教的,也弄不出结果。无奈之下,他找到了好朋友你,希望你能帮帮忙,写一个程序输出这些数列。

输入描述
数据包含多组输入。对于每组输入: 第一行一个数字N(3≤N≤25),为要找的等差数列的长度。 第二行一个数字M(1≤M≤250),为搜索双平方数的上界(即0≤p,q≤M)。

输出描述
如果没有找到数列,输出”NONE”。 如果找到了,输出一行或多行, 每行由二个整数组成:a,b。 这些行应该先按b排序再按a排序,升序。

样例输入
3
2
5
7
样例输出
0 1
0 2
2 3
0 4

1 4
37 4
2 8
29 8
1 12
5 12
13 12
17 12
5 20
2 24

分析

暴力就行了

AC代码如下:

#include <iostream>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m=2;
int map[126000];

struct node {
	int a;
	int b;
}SL[126000];


bool  cmp(node x,node y)
{
	if (x.b==y.b)
	{
		return x.a<y.a;
	} else {
		return x.b<y.b;
	}
} 
int main ()
{
	
	
	while (cin>>n>>m)
	{
		memset(map,0,sizeof (map));
		for (int i=0;i<=m;i++)
		{
			for (int j=i;j<=m;j++)
			{
				map[i*i+j*j]=1;
			}
		}
		int sum=0;
		int ans=0;
		int Max=(m*m*2)/(n-1);
		for (int i=0;i<=m*m;i++)
		{
			for (int j=1;j<=Max;j++)
			{
				bool ok=true;
				for (int k=0;k<n;k++)
				{
					if (map[i+k*j]==1&&(i+k*j)<=(m*m*2))
					{
						
					}else {
						ok=false;
						break;
					}
				
				}
				if (ok)
				{
					SL[ans].a=i;
					SL[ans].b=j;
					ans++;	
				} 
			}
		}
		if (ans==0)
		{
			cout<<"NONE"<<endl;
		}else {
			sort (SL+0,SL+ans,cmp);
			for (int i=0;i<ans;i++)
			{
				cout<<SL[i].a<<" "<<SL[i].b<<endl;
			} 
		}
		 cout<<endl;
	}
	return 0;
	
}

最后,欢迎私信交流学习
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值