浪在ACM第七次训练纯C题解

A 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 nn and SS (1≤n≤100000, 1≤S≤10的9次方)
Output
Print exactly one integer — the minimum number of coins required to obtain sum SS.
Examples
Input
5 11
Output
3
Input
6 16
Output
3

A题就不说什么了。。。

#include <stdio.h>
int main()
{
	int j,n,s,sum=0,cnt=0;
	scanf("%d %d",&n,&s);
	for(int i=n;i>=1;i--)
	{
		j=s/i;
		for(int k=1;k<=j;k++)
		{
			sum=sum+i;s=s-i;cnt++;
		}
	}
	printf("%d",cnt);
	return 0;
}

B Views Matter
You came to the exhibition and one exhibit has drawn your attention. It consists of nn stacks of blocks, where the ii-th stack consists of aiai blocks resting on the surface.

The height of the exhibit is equal to mm. Consequently, the number of blocks in each stack is less than or equal to mm.

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.
在这里插入图片描述
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 nn and mm (1≤n≤100000, 1≤m≤10的9次方) — the number of stacks and the height of the exhibit.

The second line contains nn integers a1,a2,…,ana1,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

B题先重复一下凯哥昨天讲的思路:先把每一堆排好序,然后逐个判断,从1----n-1列的判断方式是如果本列的块数比上一列的最高层数大,则最高层数加一,并且每次判断让必须留下的块数+1(其实易知1~n-1列都是只有一个的,可以直接让计数器的个数等于n-1),再判断第n列,第n列的需要必须留下的块数为:第n列的个数减去最高层数(这一点看下面那张图就很好理解),最后输出总块数减去必须留下的块数即为最多能去除的块数。
我感觉我还得解释一下我这里说的最高层的意思就是下面图中前i列在保留完毕后第i列保留块的高度,比如下面这个图,第n-1列保留块的高度为9,则最高层数就是9

在这里插入图片描述
如上图,每一列的块数分别为 1 6 6 9 12 12 12 12 13 16
由题目里所得出的规律可知第1~n-1列必须留下的个数就是n-1,所以cnt先等于n-1=9,然后看最后一列,最后一列的必须留下的块数取决于两个因素,一是这一列本身的块数,二是第n-1列的层数,因为为了保持侧视图的不变,最后一列高于最高层数的所有块都要保留,所以最后一列必须保留的块数为16-9=7,因此总共必须保留的块数cnt=9+7=16,用总块数99-16=83即为最多可以去除的块数。其他情况都是这样,有一个例外就是如果最后一层的个数和最高层数相等,那最后一层必须留下的块数为1(看图就能明白,把最后一列改成13看一看)。
还有两个注意事项:1.ai和m的大小都是小于10的9次方,数据比较大,需要定long long int(我为了方便把下面程序的整数基本都定成long long int 了)。
2.注意到n的最大取值能到10W,那好几万个数排序用普通的排序必然会超时了,这里要用快速排序,C语言库中也有自带的快速排序,不过要自己带上一小段代码判断升序还是降序,具体看代码。
建议直接记住C快排函数的用法。

#include <stdio.h>
#include <stdlib.h> //快速排序在这个头文件里
#define MAXN 100000
long long int a[MAXN];
int comp(const void*a,const void*b)
{
	return *(int*)a-*(int*)b;
} //自己写上这一段代码,判断快排是升序还是降序,这里是升序,若要降序,只需把a和b位置互换
int main()
{
	long long int n,m;
	long long int cnt=0,sum=0,mnum=0;
	scanf("%lld %lld",&n,&m);
	for(long long int i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);sum=sum+a[i]; //输入顺便求下块数总和
	}
	qsort(a,n,sizeof(long long int),comp); //快排 需要数据 数组a,数组a的长度,数组a数据类型的大小,以及comp返回的值来判断是升序还是降序。
	for(long long int i=0;i<n-1;i++) if(a[i]>mnum)mnum++; //计算出最高层数
	cnt=n-1; //根据规律直接得出前n-1列保留的块数
	if(a[n-1]-mnum>1) //判断第n列情况
	cnt+=(a[n-1]-mnum);
	else
	cnt++;
	printf("%lld",sum-cnt);
	return 0;
}

C Vasya and Book
Vasya is reading a e-book. The file of the book consists of nn pages, numbered from 11 to nn. The screen is currently displaying the contents of page xx, and Vasya wants to read the page yy. There are two buttons on the book which allow Vasya to scroll dd pages forwards or backwards (but he cannot scroll outside the book). For example, if the book consists of 1010 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 yy.
Input
The first line contains one integer tt (1≤t≤10的3次方) — the number of testcases.

Each testcase is denoted by a line containing four integers n, x, y, d (1≤n,d≤10的9次方, 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

C题先确定能够翻到指定页数的三种情况
1.能从x直接翻到y
2.从x翻到1再翻到y
3.从x翻到n再翻到y
那么这三种情况怎么判断呢,其实就是判断页数差的绝对值能否被d整除,那第一种就是abs(x-y)%d,第二种是abs(y-1)%d,第三种是abs(n-y)%d。只要这三种有一种能够符合,那就是可以翻到指定页数的。确定能够翻到指定页数后,找出翻的最小次数即可。
注意数据 能到1*10的9次方,有些数据要定longlongint。

#include <stdio.h>
#include <math.h>
int min(int x,int y) //找出最小的mind
{
	if(x>y)return y;
	else return x;
}
int main()
{
	int t;
	long long int n,x,y,d;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld %lld %lld %lld",&n,&x,&y,&d);
		if(abs(x-y)%d==0||abs(y-1)%d==0||abs(n-y)%d==0) //看三种情况有没有满足的
		{
			long long int mind=1e9; //万一后面翻的次数比较大,如果mind不够大的话会出现错误,因此让mind初始值足够大
			if(abs(x-y)%d==0) mind=abs(x-y)/d; //第一种不用多说,直接翻到,翻的次数就是abs(x-y)/d
			if(abs(y-1)%d==0) mind=min(mind,(x+d-1)/d+(y-1)/d); //第二种,先算出翻到1需要的次数,再算出从1到y的次数
			if(abs(n-y)%d==0) mind=min(mind,(n-x+d-1)/d+(n-y)/d); //第三种,先算出从x到n的次数,在算出从n到y的次数
			printf("%lld\n",mind);
		}
		else
		printf("-1\n");
	}
	return 0;
}

D - 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≤10的5次方) — 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

最后一题的题意就是替换一次S或不替换S找出最大G串。
我的思路是先统计S之前G的个数,并在此过程中不断刷新G的最大值,在遇到S后把S变成G并刷新G的最大值,然后继续读取G,刷新G的最大值,再次遇到S后 看从上一次遇到S到这次遇到S过程中读取的G并加上继续向后读取G后的值能否颠覆之前的最大值。。。S多了少了都一个道理。。我说的可能不太清楚,可以看着代码自己模拟一下试例,更有助于理解。(t…t感觉讲不明白)

#include <stdio.h>
#define MAXN 100001
char s[MAXN];
int max(int x,int y)
{
	if(x>y) return x;
	else return y;
}
int main()
{
	int n;
	scanf("%d",&n);
	scanf("%s",s);
	int maxn=0,cnt=0,k=0,sum=0;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='S') //遇s,把之前统计的G归零并用mark记录之前统计G的个数
		{
			cnt=k;k=0;
		}
		else
		{
			k++;sum++; //统计在遇到S之前G的个数
		}
		maxn=max(maxn,cnt+k+1); //找出G串最大值。 其中cnt+k+1需要好好去体会,自己模拟一下。
	}
	if(maxn>sum) maxn--; //因为我上面的cnt+k+1是默认有S要被替换的,所以有+1,假如字符串全是G就不能+1,如果+1了maxn比sum还要大1,显然是错的,要把多算的一个S减去(比如GGGG)
	printf("%d\n",maxn);
	return 0;
}

我的废话可能有点多,见谅~~
如有错误请评论指正,谢谢了~!!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值