浪在ACM 集训队第七次测试赛

A. Coins

CodeForces 1061A. Coins
  You have unlimited number of coins with values 1,2,…,n. You want to select some set of coins having the total value of S.
  It is allowed to have multiple coins with the same value in the set. What is the minimum number of coins required to get sum S?

Input

  The only line of the input contains two integers n and S (1≤n≤100000, 1≤S≤109)

Output

  Print exactly one integer — the minimum number of coins required to obtain sum S.
Examples
input
5 11
output
3
input
6 16
output
3
Note
In the first example, some of the possible ways to get sum 11 with 3 coins are:
(3,4,4)
(2,4,5)
(1,5,5)
(3,3,5)
It is impossible to get sum 11 with less than 3 coins.
In the second example, some of the possible ways to get sum 16 with 3 coins are:
(5,5,6)
(4,6,6)
It is impossible to get sum 16 with less than 3 coins.

解析

  题意大致为:给你一堆金币,金币的币面不超过n,让你用从1~n的钱凑出s元来,求最少用的金币的个数,相同币面的金币可以重复使用。
  简单的贪心,及先拿价值最大的,再用价值小的凑数。当s可以整除n时,都用n来凑,所用的个数最少。但s%n=m时,我们可以知道,m<n,先用n凑到s/n*n的数,再用m凑上,为最小的个数。

#include<iostream>  //头文件
#include<algorithm>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#ifndef NULL
#define NULL 0
#endif
using namespace std;


int main()
{
	int s, n;
	cin >> n >> s;
	if (s%n==0)
		cout << s / n<<endl;
	else
		cout << s / n + 1 << endl;
	return 0;
}

B.Views Matter

CodeForces 1061B.Views Matter
  You came to the exhibition and one exhibit has drawn your attention. It consists of n stacks of blocks, where the i-th stack consists of ai blocks resting on the surface.
The height of the exhibit is equal to m. Consequently, the number of blocks in each stack is less than or equal to m.
  There is a camera on the ceiling that sees the top view of the blocks and a camera on the right wall that sees the side view of the blocks.
codeforce
Find the maximum number of blocks you can remove such that the views for both the cameras would not change.
  Note, that while originally all blocks are stacked on the floor, it is not required for them to stay connected to the floor after some blocks are removed. There is no gravity in the whole exhibition, so no block would fall down, even if the block underneath is removed. It is not allowed to move blocks by hand either.

Input

  The first line contains two integers n and m (1≤n≤100000, 1≤m≤109) — the number of stacks and the height of the exhibit.
  The second line contains n integers a1,a2,…,an (1≤ai≤m) — the number of blocks in each stack from left to right.

Output

Print exactly one integer — the maximum number of blocks that can be removed.
Examples
input
5 6
3 3 3 3 3
output
10
input
3 5
1 2 4
output
3
input
5 5
2 3 1 4 4
output
9
input
1 1000
548
output
0
input
3 3
3 1 1
output
1
Note
The following pictures illustrate the first example and its possible solution.
Blue cells indicate removed blocks. There are 10 blue cells, so the answer is 10.
codeforce

解析

题意大致为,有一个物体,由一堆方块组成(minecraft嘿嘿),让你在保证右视图和俯视图不变的情况下,尽可能多的取走方块,方块无视重力(minecraft嘿嘿)。
第一反应,桶数组处理。数据109开不出来=*=。只好闷头总结规律。
可以知道每一列必须至少留有一块。每一行必须至少留有一块。

总结一下规律
1.第i列要么保留 第i-1列所保留方块行数+1的方块,要么与第i-1列保留的方块平行。这样保证了俯视图不变
2.当右视图高度为m,最后一行保留的方块高为n是,那么从保留的第n块方块向上数m-n的方块也要保留。
在从小到大排序后,结合上两条保证右视图不变

第一种.
3*5的方块,俯视图为5,右视图为3
3*5的方块
按照规律取后为
取后为
第二类摆法
5列,4行
5列,4行
按照规律取后为
2333

#include<iostream>  //头文件
#include<algorithm>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#ifndef NULL
#define NULL 0
#endif
using namespace std;

typedef long long ll;
ll a[100010];
int main()
{
	ll n,m,sum=0;	
	cin>>n>>m;
	for(ll i=0;i<n;i++)
		cin>>a[i];
	sort(a,a+n);
	ll j=1;
	for(ll i=0;i<n-1;i++)
		if(a[i]>=j){
			sum+=a[i]-1;
			j++;
		}
		else
			sum+=a[i]-1;
	if(a[n-1]>=j)    //最后一个特判一下
		sum+=j-1;
	else
		sum+=a[n-1]-1;
	cout<<sum<<endl;
	return 0;
} 

C.Vasya and Book

CodeForces 1082A.Vasya and Book
  Vasya is reading a e-book. The file of the book consists of n pages, numbered from 1 to n. The screen is currently displaying the contents of page x, and Vasya wants to read the page y. There are two buttons on the book which allow Vasya to scroll d pages forwards or backwards (but he cannot scroll outside the book). For example, if the book consists of 10 pages, and d=3, then from the first page Vasya can scroll to the first or to the fourth page by pressing one of the buttons; from the second page — to the first or to the fifth; from the sixth page — to the third or to the ninth; from the eighth — to the fifth or to the tenth.
  Help Vasya to calculate the minimum number of times he needs to press a button to move to page y.

Input

  The first line contains one integer t (1≤t≤103) — the number of testcases.
  Each testcase is denoted by a line containing four integers n, x, y, d (1≤n,d≤109, 1≤x,y≤n) — the number of pages, the starting page, the desired page, and the number of pages scrolled by pressing one button, respectively.

Output

  Print one line for each test.
  If Vasya can move from page x to page y, print the minimum number of times he needs to press a button to do it. Otherwise print −1.
Example
input
3
10 4 5 2
5 1 3 4
20 4 19 3
output
4
-1
5
Note
In the first test case the optimal sequence is: 4→2→1→3→5.
In the second test case it is possible to get to pages 1 and 5.
In the third test case the optimal sequence is: 4→7→10→13→16→19.

解析

大意:这货不知道哪来的垃圾电子书,一次只能翻d页,但是无论第一页到第x页或者第n页到第x页是否为d的倍数,都可以翻过去。然后问你能不能从x页翻到第y页。为什么不去换个机子
简单数学题:如果可以直接从y到x,那么必定abs(y-x)%d== 0
如果从x到y无法直接翻过去。那么判断一下可否中转。及(y-1)%d== 0||(n-y)%d==0如果成立,那么就是(y-1)/d+(x-1)/d+1或者(n-y)/d+(n-x)/d+1。
为什么一定要+1,我……懒得证明

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#ifndef NULL
#define NULL 0
#endif
using namespace std;

int main()
{
	long long t, n, x, y, d,minn=-1;
	cin >> t;
	while (t--) {
		cin >> n >> x >> y >> d;
		long long a=n, b=n;
		if (abs(y - x) % d == 0){
			cout<<abs(y - x) / d<<endl;
			continue;
		}
		if (((y - 1) % d == 0))
			a = (y - 1) / d + (x - 1) / d+1;
		if(((n - y) % d == 0))
			b = (n - y) / d + (n - x) / d+1;
		if (min(a,b)!= n)
			cout << min(a, b)<<endl;
		else
			cout << -1 << endl;
	}
	return 0;
}

D.Vova and Trophies

CodeForces 1082B.Vova and Trophies
  Vova has won n trophies in different competitions. Each trophy is either golden or silver. The trophies are arranged in a row.
  The beauty of the arrangement is the length of the longest subsegment consisting of golden trophies. Vova wants to swap two trophies (not necessarily adjacent ones) to make the arrangement as beautiful as possible — that means, to maximize the length of the longest such subsegment.
  Help Vova! Tell him the maximum possible beauty of the arrangement if he is allowed to do at most one swap.

Input

  The first line contains one integer n (2≤n≤105) — the number of trophies.
  The second line contains n characters, each of them is either G or S. If the i-th character is G, then the i-th trophy is a golden one, otherwise it’s a silver trophy.

Output

  Print the maximum possible length of a subsegment of golden trophies, if Vova is allowed to do at most one swap.
Examples
input
10
GGGSGGGSGG
output
7
input
4
GGGG
output
4
input
3
SSS
output
0
Note
  In the first example Vova has to swap trophies with indices 4 and 10. Thus he will obtain the sequence “GGGGGGGSGS”, the length of the longest subsegment of golden trophies is 7.
  In the second example Vova can make no swaps at all. The length of the longest subsegment of golden trophies in the sequence is 4.
  In the third example Vova cannot do anything to make the length of the longest subsegment of golden trophies in the sequence greater than 0.

解析

题意:给你一串奖牌,金牌和银牌,要求你只交换一次,交换一个奖牌,使得金牌在一块更多。谁知道这大佬怎么这么多奖牌
从左往右存一下s左面有多少个g,最后再存一下末尾到最后一个s之间有多少个g。然后递推求就可以了。
1
2
3

#include<iostream>  //头文件
#include<algorithm>
#include<cstring>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
#ifndef NULL
#define NULL 0
#endif
using namespace std;

char s[100010];
int a[100010];
int main()
{
	int n,t=0,j=0,maxx=0;
	cin>>n>>s;
	for(int i=0;i<n;i++)
		if(s[i]=='S'){
			a[t]=j;
			j=0;
			t++;
		}
		else if(s[i]=='G')
			j++;
	a[t]=j;
	for(int i=0;i<t;i++)
		if(a[i]+a[i+1]>0)
			if(maxx<=a[i]+a[i+1]){  //如果这俩s左边和大于maxx,更新maxx
				maxx=a[i]+a[i+1];
				if(n-t>maxx)  //如果这两个s所代表的g的个数,小于总g的个数
				//那么把夹在g之间的s换成其他地方的g,使得maxx++
					maxx++;
			}
	if(t==0)  //如果没有s,则直接输出从左往右数的g的个数。
		cout<<a[t]<<endl;
	else 
		cout<<maxx<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值