HPU personal training

HPU personal training

A - Engines
Problem Statement
E869120 is initially standing at the origin (0,0) in a two-dimensional plane.
He has N engines, which can be used as follows:
When E869120 uses the i-th engine, his X- and Y-coordinate change by xi and yi, respectively. In other words, if E869120 uses the i-th engine from coordinates (X,Y), he will move to the coordinates (X+xi,Y+yi).
E869120 can use these engines in any order, but each engine can be used at most once. He may also choose not to use some of the engines.
He wants to go as far as possible from the origin. Let (X,Y) be his final coordinates. Find the maximum possible value of √X2+Y2 , the distance from the origin.
Constraints
1≤N≤100
−1 000 000≤xi≤1 000 000
−1 000 000≤yi≤1 000 000
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N
x1 y1
x2 y2
: :
xN yN
Output
Print the maximum possible final distance from the origin, as a real value. Your output is considered correct when the relative or absolute error from the true answer is at most 10−10.
Sample Input 1
3
0 10
5 -5
-5 -5
Sample Output 1
10.000000000000000000000000000000000000000000000000
The final distance from the origin can be 10 if we use the engines in one of the following three ways:
Use Engine 1 to move to (0,10).
Use Engine 2 to move to (5,−5), and then use Engine 3 to move to (0,−10).
Use Engine 3 to move to (−5,−5), and then use Engine 2 to move to (0,−10).
The distance cannot be greater than 10, so the maximum possible distance is 10.
Sample Input 2
5
1 1
1 0
0 1
-1 0
0 -1
Sample Output 2
2.828427124746190097603377448419396157139343750753
The maximum possible final distance is 2√2 =2.82842…. One of the ways to achieve it is:
Use Engine 1 to move to (1,1), and then use Engine 2 to move to (2,1), and finally use Engine 3 to move to (2,2).
Sample Input 3
5
1 1
2 2
3 3
4 4
5 5
Sample Output 3
21.213203435596425732025330863145471178545078130654
If we use all the engines in the order 1→2→3→4→5, we will end up at (15,15), with the distance 15√2 =21.2132… from the origin.
Sample Input 4
3
0 0
0 1
1 0
Sample Output 4
1.414213562373095048801688724209698078569671875376
There can be useless engines with (xi,yi)=(0,0).
Sample Input 5
1
90447 91000
Sample Output 5
128303.000000000000000000000000000000000000000000000000
Note that there can be only one engine.
Sample Input 6
2
96000 -72000
-72000 54000
Sample Output 6
120000.000000000000000000000000000000000000000000000000
There can be only two engines, too.
Sample Input 7
10
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
Sample Output 7
148.660687473185055226120082139313966514489855137208

题目大意:坐标系中的点,问哪两个点组合起来的点距离远点最远。
解题思路:可以将每个点看做从原点发出的向量。然后向量加起来最大的就是最远的距离。两条向量的夹角越小,他们合成的向量就越长。所以需要先比较所有边之间的夹角大小,然后暴力遍历所有情况,每次都更新最大值为ans,然后开根号。

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1100;

struct node{
	ll x,y;
}r[maxn];

bool cmp(node a,node b){
	return atan2(a.x,a.y)<atan2(b.x,b.y);
}

int main(){
	ll n,x,y;
	cin>>n;
	for(ll i=0;i<n;i++) cin>>r[i].x>>r[i].y;
	sort(r,r+n,cmp);
	ll ans=0;
	for(ll i=0;i<n;i++){
		x=r[i].x;y=r[i].y;
		ans=max(ans,x*x+y*y);
		for(ll j=(i+1)%n;j!=i;j=(j+1)%n){
			x+=r[j].x;
			y+=r[j].y;
			ans=max(ans,x*x+y*y);
		}
	}
	double Ans=sqrt(ans);
	printf("%.13lf\n",Ans);
	
	return 0;
}

这里用的atan2()函数求与x轴的夹角会存在精度损失,但是并不影响做这道题。

B - Consecutive Integers
Problem Statement
Snuke has N integers: 1,2,[ldots],N. He will choose K of them and give those to Takahashi.
How many ways are there to choose K consecutive integers?
Constraints
All values in input are integers.
1≤K≤N≤50
Input
Input is given from Standard Input in the following format:
N K
Output
Print the answer.
Sample Input 1
3 2
Sample Output 1
2
There are two ways to choose two consecutive integers: (1,2) and (2,3).
Sample Input 2
13 3
Sample Output 2
11

题目大意:给你一个K和N,让你从这N个数中找到连续的K个数,问有几种。
解题思路:观察样例可以看出ans=N-K+1,事实上也就是这样。很容易看出的一个结论。

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
	int n,k;
	cin>>n>>k;
	cout<<n-k+1<<endl;
	return 0;
}

C - ModSum
Problem Statement
For an integer N, we will choose a permutation {P1,P2,…,PN} of {1,2,…,N}.
Then, for each i=1,2,…,N, let Mi be the remainder when i is divided by Pi.
Find the maximum possible value of M1+M2+[cdots]+MN.
Constraints
N is an integer satisfying 1≤N≤109.
Input
Input is given from Standard Input in the following format:
N
Output
Print the maximum possible value of M1+M2+[cdots]+MN.
Sample Input 1
2
Sample Output 1
1
When the permutation {P1,P2}={2,1} is chosen, M1+M2=1+0=1.
Sample Input 2
13
Sample Output 2
78
Sample Input 3
1
Sample Output 3
0

题目大意:给你一个n,集合中有从1到n这些数。用第i个数模上i然后所有的相加,问结果的最大可能。
解题思路:按样例找规律,推测当n=1时最大值为0,n=2时最大值为1,n等于3时最大值为3,n等于4时最大值为6,依次加4加5加6…也就是ans=(n*(n-1))/2用样例证明一下n等于13时1312/2=78.所以答案就是(n(n-1))/2

这个题三次才过,第二次在第一次的基础上开了long long,第三次是把第二次的0.5改为/2了。但是我也不太清楚是为什么一改就可以了。(如果有明白的大佬可以给我指点迷津),问了问其他大佬,解释是0.5 结果已经是double了,然后double又转longlong,可能有精度损失(装作听懂了的样子)

#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
	ll a;
	while(cin>>a)
	{
		ll ans;
		if(a%2==0)
		ans=a/2*(a-1);
		else ans=(a-1)/2*a;
		cout<<ans<<endl;
	}
	return 0;
}

F - Monsters Battle Royale
Problem Statement
There are N monsters, numbered 1,2,…,N.
Initially, the health of Monster i is Ai.
Below, a monster with at least 1 health is called alive.
Until there is only one alive monster, the following is repeated:
A random alive monster attacks another random alive monster.
As a result, the health of the monster attacked is reduced by the amount equal to the current health of the monster attacking.
Find the minimum possible final health of the last monster alive.
Constraints
All values in input are integers.
2≤N≤105
1≤Ai≤109
Input
Input is given from Standard Input in the following format:
N
A1 A2 … AN
Output
Print the minimum possible final health of the last monster alive.
Sample Input 1
4
2 10 8 40
Sample Output 1
2
When only the first monster keeps on attacking, the final health of the last monster will be 2, which is minimum.
Sample Input 2
4
5 13 8 1000000000
Sample Output 2
1
Sample Input 3
3
1000000000 1000000000 1000000000
Sample Output 3
1000000000

题目大意:给你一个n,然后给了n个数为n个怪兽的血量。每次一个怪兽攻击另一个,受到的伤害为攻击方的血量。问攻击完若干次后最少的血量的怪兽他的血量值为多少。
解题思路:刚开始我认为是只要有一个奇数,还有另一个与它血量不同的怪兽,那么最后就是输出1,如果血量都相同,那么就不变。如果都是偶数,有至少两个血量不同,那么就是输出2.后来交了一发直接wa了。是样例迷惑了我。仔细想想只要两个存在公因数那么就一定不会是我想的那种情况。所以正确的方法是取他们所有数的gcd,然后这个gcd即为最少的血量。

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int a[maxn];
int main()
{
	int n,ans;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	ans=a[0];
	for(int i=1;i<n;i++)
	{
		ans=__gcd(ans,a[i]);
	}
	cout<<ans<<endl;
	return 0;
}

G - Powerful Discount Tickets
Problem Statement
Takahashi is going to buy N items one by one.
The price of the i-th item he buys is Ai yen (the currency of Japan).
He has M discount tickets, and he can use any number of them when buying an item.
If Y tickets are used when buying an item priced X yen, he can get the item for X 2Y (rounded down to the nearest integer) yen.
What is the minimum amount of money required to buy all the items?
Constraints
All values in input are integers.
1≤N,M≤105
1≤Ai≤109
Input
Input is given from Standard Input in the following format:
N M
A1 A2 … AN
Output
Print the minimum amount of money required to buy all the items.
Sample Input 1
3 3
2 13 8
Sample Output 1
9
We can buy all the items for 9 yen, as follows:
Buy the 1-st item for 2 yen without tickets.
Buy the 2-nd item for 3 yen with 2 tickets.
Buy the 3-rd item for 4 yen with 1 ticket.
Sample Input 2
4 4
1 9 3 5
Sample Output 2
6
Sample Input 3
1 100000
1000000000
Sample Output 3
0
We can buy the item priced 1000000000 yen for 0 yen with 100000 tickets.
Sample Input 4
10 1
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
Sample Output 4
9500000000

题目大意:题目就是给你一个n和m,然后给你n个数为票价,问这n张票可以经过m次打折,每次都是打五折(个人理解的,反正意思也就是这样~),问最后最少票价为多少。
解题思路:这道题需要用到贪心策略。每次都用最贵的那个去打折,然后打折次数用完后得到的就是最少的票价。开始我用的是sort排序,然后每次都排,一共排m次,果不其然超时了。然后我的想法是存到set里,自动排序,然后只需要取最后一个让他打折,然后放进去,然后取出来打折,放进去,后来才明白set内的元素只可以读,不可以写,最后用了优先队列,每次都弹出队首元素,然后让它打折,然后放进去。全部打完折就累加起来。

#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
priority_queue<int>q;
int main()
{
	int n,m;
	ll x;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		cin>>x;
		q.push(x);
	}
	for(int i=0;i<m;i++)
	{
		if(!q.empty())
		{
			int t;
			t=q.top();
			t=t/2;
			q.pop();
			q.push(t);
		}
	}
	ll sum=0;
	while(!q.empty())
	{
		sum+=q.top();
		q.pop();
	}
	cout<<sum<<endl;
	return 0;
}

H - Attack Survival
Problem Statement
Takahashi has decided to hold fastest-finger-fast quiz games. Kizahashi, who is in charge of making the scoreboard, is struggling to write the program that manages the players’ scores in a game, which proceeds as follows.
A game is played by N players, numbered 1 to N. At the beginning of a game, each player has K points.
When a player correctly answers a question, each of the other N−1 players receives minus one (−1) point. There is no other factor that affects the players’ scores.
At the end of a game, the players with 0 points or lower are eliminated, and the remaining players survive.
In the last game, the players gave a total of Q correct answers, the i-th of which was given by Player Ai. For Kizahashi, write a program that determines whether each of the N players survived this game.
Constraints
All values in input are integers.
2≤N≤105
1≤K≤109
1≤Q≤105
1≤Ai≤N (1≤i≤Q)
Input
Input is given from Standard Input in the following format:
N K Q
A1
A2
.
.
.
AQ
Output
Print N lines. The i-th line should contain Yes if Player i survived the game, and No otherwise.
Sample Input 1
6 3 4
3
1
3
2
Sample Output 1
No
No
Yes
No
No
No
In the beginning, the players’ scores are (3,3,3,3,3,3).
Player 3 correctly answers a question. The players’ scores are now (2,2,3,2,2,2).
Player 1 correctly answers a question. The players’ scores are now (2,1,2,1,1,1).
Player 3 correctly answers a question. The players’ scores are now (1,0,2,0,0,0).
Player 2 correctly answers a question. The players’ scores are now (0,0,1,−1,−1,−1).
Players 1,2,4,5 and 6, who have 0 points or lower, are eliminated, and Player 3 survives this game.
Sample Input 2
6 5 4
3
1
3
2
Sample Output 2
Yes
Yes
Yes
Yes
Yes
Yes
Sample Input 3
10 13 15
3
1
4
1
5
9
2
6
5
3
5
8
9
7
9
Sample Output 3
No
No
No
No
Yes
No
No
No
Yes
No

题目大意:给你一个n为n个战士,然后给一个k,每个人初始血量都为k,给一个q,是需要进行四次受伤害。每次伤害都有一个可以免伤,就是q组数据。问最后哪些战士活着,哪些战士死了。
解题思路:可以让所有战士都受到q点伤害,然后再加上每个人免伤的次数,也就是少受到的伤害。最后判断血量大于0的活着,小于等于0的死了。

#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll sq[maxn];
int main()
{
	ll n,k,q,m;
	cin>>n>>k>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>m;
		sq[m]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(k-q+sq[i]>0) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}

I - Lower
Problem Statement
There are N squares arranged in a row from left to right.
The height of the i-th square from the left is Hi.
You will land on a square of your choice, then repeat moving to the adjacent square on the right as long as the height of the next square is not greater than that of the current square.
Find the maximum number of times you can move.
Constraints
All values in input are integers.
1≤N≤105
1≤Hi≤109
Input
Input is given from Standard Input in the following format:
N
H1 H2 … HN
Output
Print the maximum number of times you can move.
Sample Input 1
5
10 4 8 7 3
Sample Output 1
2
By landing on the third square from the left, you can move to the right twice.
Sample Input 2
7
4 4 5 6 6 5 5
Sample Output 2
3
By landing on the fourth square from the left, you can move to the right three times.
Sample Input 3
4
1 2 3 4
Sample Output 3
0

题目大意:给你一个n,从左到右有n个正方形,然后第i个正方形的高度为Hi,你可以降落到某一个正方形上然后重复移动到右边的高度不大于当前高度的正方形上。找出最大可以移动的步数。

解题思路:直接从左往右遍历一遍,如果下一个高度小于当前高度,那么步数加1,如果下一个高度大于当前高度,那么用步数和ans取最大值,再将步数初始化,最后输出ans。

#include<iostream>
using namespace std;
const int maxn=1e5+10;
int h[maxn];
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>h[i];
	}
	int t=0,ans=0;
	for(int i=1;i<n;i++)
	{
		if(h[i]<=h[i-1])
		{
			t++;
			ans=max(ans,t);
		}
		else t=0;
	}
	cout<<ans<<endl;
	return 0;
}

M - AB Substrings
Problem Statement
Snuke has N strings. The i-th string is si.
Let us concatenate these strings into one string after arranging them in some order. Find the maximum possible number of occurrences of AB in the resulting string.
Constraints
1≤N≤104
2≤|si|≤10
si consists of uppercase English letters.
Input
Input is given from Standard Input in the following format:
N
s1
\vdots
s_N
Output
Print the answer.
Sample Input 1
3
ABCA
XBAZ
BAD
Sample Output 1
2
For example, if we concatenate ABCA, BAD and XBAZ in this order, the resulting string ABCABADXBAZ has two occurrences of AB.
Sample Input 2
9
BEWPVCRWH
ZZNQYIJX
BAVREA
PA
HJMYITEOX
BCJHMRMNK
BP
QVFABZ
PRGKSPUNA
Sample Output 2
4
Sample Input 3
7
RABYBBE
JOZ
BMHQUVA
BPA
ISU
MCMABAOBHZ
SZMEHMA
Sample Output 3
4

题目大意:给你n个字符串,可以任意排列先后顺序,找出一种排列方式使得其中含有的AB字符最多,并输出这个值。

解题思路:先将每个字符都遍历一遍,找出每个字符中含有完整的AB个数,然后再找出开头为B的字符有多少个,找出结尾为A的字符有多少个, 在找出开头为B结尾为A的字符串有多少个,最后判断用AB个数加上min(A,B),如果A的个数等于B的个数,并且等于开头为B结尾为A的个数,并且不为0,那么ans就减一。

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
string s[maxn];
int main()
{
	int n;
	int d=0,a=0,b=0,ab=0;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>s[i];
	}
	for(int i=0;i<n;i++)
	{
		for(int j=1;j<s[i].size();j++)
		{
			if(s[i][j-1]=='A'&&s[i][j]=='B')
			{
				d++;
			}
		}
	}
	for(int i=0;i<n;i++)
	{
		if(s[i][0]=='B') b++;
		if(s[i][s[i].size()-1]=='A') a++;
		if(s[i][0]=='B'&&s[i][s[i].size()-1]=='A') ab++;
	}
	int ans=0;
	ans=d+min(b,a);
	if(b==a&&b==ab&&b!=0) ans--;
	cout<<ans<<endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值