寒假训练第一周总结

  • 这一周有三次比赛,有许多题都不能很快的有思路,那些算法自己都没有学过不会用,写起来非常吃力,我决定通过比赛了解有哪些算法自己慢慢学习。

[NOIP2005 普及组] 采药

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入格式

第一行有 $2$ 个整数 $T$($1 \le T \le 1000$)和 $M$($1 \le M \le 100$),用一个空格隔开,$T$ 代表总共能够用来采药的时间,$M$ 代表山洞里的草药的数目。

接下来的 $M$ 行每行包括两个在 $1$ 到 $100$ 之间(包括 $1$ 和 $100$)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式

输出在规定的时间内可以采到的草药的最大总价值。

样例 #1

样例输入 #1

70 3
71 100
69 1
1 2

样例输出 #1

3

提示

【数据范围】

  • 对于 $30%$ 的数据,$M \le 10$;
  • 对于全部的数据,$M \le 100$。

【题目来源】

NOIP 2005 普及组第三题

解析:

本题是一个(动态规划)背包问题也是我第一次遇到,看了网上的教学视频后才知道这个方法。
所谓背包问题的解答:首先建立一个二维数组,第一行第一列都为0,从a[1][1]开始判断编号为1;容量为1时背包能装入的最大值,分两种情况一、如果装不下当前物品,那么前n个物品的最佳组合和前n-1给物品的最佳组合是一样的。二、如果装得下当前物品,1.装当前物品,在给当前物品预留了相应空间的情况下,前n-1个物品的最佳组合加上当前物品的价值就是总价值。2.不装当前物品,那么前n-1个物品和前n个物品的最佳组合是一样的;选取较大的价值,就是当前最佳组合的价值。

`#include<stdio.h>
int max(int a,int b);
int main(void){

int t,m;
int f[110][1100];
int w[110],v[110];
scanf("%d%d",&t,&m);
for(int i=1;i<=m;i++){//i从1开始取i为0时其任意数组的值都为0;
	scanf("%d%d",&w[i],&v[i]);
}
for(int i=1;i<=m;i++){
	for(int j=1;j<=t;j++){
		if(w[i]>j){//第i件物品大于背包容量
			f[i][j]=f[i-1][j];
		}
		else {//第i件物品小于背包容量,判断装与不装价值大小
			f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
		}
	}
}
printf("%d",f[m][t]);

return 0;
}
int max(int a,int b ){
int x;
x=(a>b?a:b);
return x;
}
`
2.

标题计数

题目背景

5ab 试图帮洛谷写机器人,数题解中有多少个一级标题。

题目描述

Markdown 是一种标记语言。在 Markdown 中,若一行的第一个非空白字符是井号(#),且紧跟着若干个空格,则这一行剩余的非空白内容将会按照一级标题渲染。

在本题范围内,下面的都是一级标题:

# This is a title
#    This is another title
    # This is also a title
    #   You#can#add#more#sharps
# #

在本题范围内,下面的都不是一级标题:

<h1>an HTML title</h1>
#You should insert a space
## This is a secondary title
aaaaa # This is not a title at all
 # 
You should add something after the sharp sign

给定一段多行文本,求出这段文本总共有多少个一级标题。

输入格式

第一行输入一个整数 $n$,代表文本的行数。

接下来输入 $n$ 行,是给出的标记文本。

输出格式

输出一行一个整数,为这段文本中的一级标题个数。

样例 #1

样例输入 #1

1
#u#n#t#i#t#l#e#d#

样例输出 #1

0

样例 #2

样例输入 #2

1
# a perfect title

样例输出 #2

1

样例 #3

样例输入 #3

10
# a
 # b
## c
#d
#  
e
# f#g#h#i#j
  ##k
# #
l # m

样例输出 #3

4

提示

样例 3 解释

第 2,3,8,10 行(文本第 1,2,7,9 行)是满足条件的一级标题。


如果选手在比赛中使用 Windows 系统,则直接从网站或下发题面中复制的样例的换行符是 CRLF,与真实数据中的 LF 会有区别。为了方便调试,建议使用下发文件中的样例进行测试,并直接使用文件输入输出。

数据规模与约定

总文本不超过 $100$ 个字符,不超过 $10$ 行。文本中只有英文字母,井号(#),换行符(Line Feed,LF,\n)和空格。

解析:先判断前面字符是否为空格或者井号,空格继续,井号继续进入新循环判断,如果紧接着不是空格跳出循环;如果碰到非空格标识符c加1记录;如果一直为空格,到达'\0'退出循环判断下一个字符串;
代码:`#include<stdio.h>
int main(){

int i,j,n,t,c=0,x=0;
char a[10000]={0};
scanf("%d",&n);
getchar();//**注意用gets()时加getchar()**
for(i=0;i<n;i++){
	gets(a);
	for(j=0;a[j]!='\0';j++){
		if(x==1){
			x=0;
			break;
		}
		if(a[j]==' '){
			continue;
		}
		else if(a[j]=='#'){
			for(t=j+1;a[t]!='\0';t++){
				if((t==j+1)&&(a[t]!=' ')){
					x=1;
					break;
				}
				if(a[t]==' ') continue;
				if(a[t]!=' ') {
					c++;
					x=1;
					break;
				}
			}
		}
		else break;
	}
}
printf("%d\n",c);
return 0;

}
`

[蓝桥杯 2017 省 AB] 分巧克力

题目描述

儿童节那天有 $K$ 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 $N$ 块巧克力,其中第 $i$ 块是 $H_i \times W_i$ 的方格组成的长方形。

为了公平起见,小明需要从这 $N$ 块巧克力中切出 $K$ 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数。

  2. 大小相同。

例如一块 $6 \times 5$ 的巧克力可以切出 $6$ 块 $2 \times 2$ 的巧克力或者 $2$ 块 $3 \times 3$ 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小 $H_i$ 计算出最大的边长是多少么?

输入格式

第一行包含两个整数 $N$ 和 $K$。$(1 \le N,K \le 10^5)$。

以下 $N$ 行每行包含两个整数 $H_i$ 和 $W_i$。$(1 \le H_i,W_i \le 10^5)$。

输入保证每位小朋友至少能获得一块 $1 \times 1$ 的巧克力。

输出格式

输出切出的正方形巧克力最大可能的边长。

样例 #1

样例输入 #1

2 10  
6 5  
5 6

样例输出 #1

2

提示

蓝桥杯 2022 省赛 A 组 I 题。

解析:切出巧克力最大边长为100000,最小为1;
将每块巧克力的长宽记录下来,若h为长,w为宽,mid为切出正方形的边长,第i块巧克力能切出h/mid*w/mid块巧克力;
通过二分(二分可以大大缩短查找时间)找到刚好等于小朋友人数的边长的巧克力;
代码:
`#include<stdio.h>
int h[100000];
int w[100000];
int main(){

int n,k,i,c=0,max=100000,min=1;
scanf("%d%d",&n,&k);
for(i=0;i<n;i++){
	scanf("%d%d",&h[i],&w[i]);
}
while(min<=max){
	int mid=(max+min)/2;
	int cnt=0;
	for(i=0;i<n;i++){
		cnt+=(h[i]/mid)*(w[i]/mid);
	}
	if(cnt>=k){
		min=mid+1;
		c=mid;
	}
	else{
		max=mid-1;
	}
}
printf("%d",c);
return 0;

}`

·通过其他的题目还了解到,如果测试数据小可以打表(如约瑟夫),有些题目如果你了解到他的意思,还可以用数学公式来很快的解决(如毕业后)。

posted @ 2024-01-28 10:49  千空7  阅读(14)  评论(0)    收藏  举报