北理工集训 Day1—Day2 (部分算法题目)

目录

P1678 烦恼的高考志愿

用C++进行代码实现

P2440 木材加工

 用C++进行代码实现

P5705 【深基2.例7】数字反转

代码实现

P3954 [NOIP 2017 普及组] 成绩

代码实现

P5709 【深基2.习6】Apples Prologue / 苹果和虫子

 代码实现

P5703 【深基2.例5】苹果采购

 代码实现

P5706 【深基2.例8】再分肥宅水

 代码实现

P5712 【深基3.例4】Apples

 代码实现

P5720 【深基4.例4】一尺之棰

 代码实现

        P5723 【深基4.例13】质数口袋

 代码实现

P1226 【模板】快速幂||取余运算

代码实现

P5733 【深基6.例1】自动修正

 代码实现

P5743 【深基7.习8】猴子吃桃

         代码实现

P5735 【深基7.例1】距离函数

 代码实现

        P5727 【深基5.例3】冰雹猜想

代码实现


P1678 烦恼的高考志愿

题目背景

计算机竞赛小组的神牛V神终于结束了高考,然而作为班长的他还不能闲下来,班主任老t给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是v神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。

题目描述

现有 m(m\le100000)m(m≤100000) 所学校,每所学校预计分数线是 a_i(a_i\le10^6)ai​(ai​≤106)。有 n(n\le100000)n(n≤100000) 位学生,估分分别为 b_i(b_i\le10^6)bi​(bi​≤106)。

根据n位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。

输入格式

第一行读入两个整数m,n。m表示学校数,n表示学生数。第二行共有m个数,表示m个学校的预计录取分数。第三行有n个数,表示n个学生的估分成绩。

输出格式

一行,为最小的不满度之和。

输入输出样例

说明/提示

数据范围:

对于30%的数据,m,n<=1000,估分和录取线<=10000;

对于100%的数据,n,m<=100,000,录取线<=1000000。

用C++进行代码实现

#include<stdio.h>
#include<algorithm>
#define cwh(i,x,y) for (register int i=x;i<=y;++i)
using namespace std;
int a,b,ans;
int c[100001],d[100001];//c是学校预计分数线,d是估分
int main()
{
	scanf("%d%d",&a,&b);
    cwh(i,1,a) scanf("%d",&c[i]);
    cwh(i,1,b) scanf("%d",&d[i]);
    sort (c+1,c+1+a);//从低到高排序
    cwh(i,1,b)//二分模板
    {
    	int l=0,r=a+1;
    	while(l<r)
    	{
    		int mid=(r+l)/2;
    		if(c[mid]<=d[i])
            l=mid+1;
			else r=mid;	
    	}
    	if(c[1]>=d[i])ans+=c[1]-d[i];//特判
    	else ans+=min(abs(c[l-1]-d[i]),abs(c[l]-d[i]));//求min
    }
	printf("%d",ans);//输出
    return 0;
}

P2440 木材加工

题目背景

要保护环境

题目描述

木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有剩余),需要得到的小段的数目是给定的。当然,我们希望得到的小段木头越长越好,你的任务是计算能够得到的小段木头的最大长度。木头长度的单位是cm。原木的长度都是正整数,我们要求切割得到的小段木头的长度也是正整数。

例如有两根原木长度分别为11和21,要求切割成到等长的6段,很明显能切割出来的小段木头长度最长为5.

输入格式

第一行是两个正整数N和K(1 ≤ N ≤ 100000,1 ≤ K ≤ 100000000),N是原木的数目,K是需要得到的小段的数目。

接下来的N行,每行有一个1到100000000之间的正整数,表示一根原木的长度。

输出格式

能够切割得到的小段的最大长度。如果连1cm长的小段都切不出来,输出”0”。

输入输出样例

 用C++进行代码实现

#include <iostream>//洛谷 p2440 木材加工
#include <algorithm>
using namespace std;
int a[100010], n, k, ans, ma;
//a[i]用来记录第 i 块木头长度, ma 是最长的木头的长度, ans 最终要求的结果; 
bool cmp(int a, int b) {
	return a > b;
}
int main() {
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		ma = max(ma, a[i]);//找到最长的木头长度; 
	}
	sort(a, a + n, cmp);//将木头按长度由长到短排列; 
	int lf, ri, md, sum;
	lf = 0;
	ri = ma;//令 ri 初始值为 ma, 因为所有木头长度都小于等于 ma;  
	//lf 长度左值, ri 长度右值, md 中间长度值;
	// sum 获得的 md 长度木块的数量; 
	while (lf <= ri) {
		sum = 0;
		md = lf + (ri - lf) / 2;
		if (md == 0) {
	//md == 0 即 md 大于 1 不能得到 sum 个长
	//为 md 的木块,使 sum == k, 返回结果 ans == 0; 
			ans = 0;
			break;
		}
		for (int i = 0; i < n; i++) {// 遍历所有木块找到比 md 长度小的木块; 
			if (a[i] >= md) {
				sum += a[i] / md; 
			}
			else {
		//如果长度小于 md, 即结束循环, 因为数组 a 已是下降序列, 之后的数也小于 md; 
				break;
			}
		}
		if (sum >= k) { //此时证明 md 数值小于或等于我们求的最终结果; 
			ans = md;//先令结果 ans == md 以作进一步判断; 
			lf = md + 1;
		}
		else {//证明 md 数值过大求不出结果; 
			ri = md - 1; 
		}
	}
	cout << ans << endl;
	return 0;
}

P5705 【深基2.例7】数字反转

题目描述

输入一个不小于 100100 且小于 10001000,同时包括小数点后一位的一个浮点数,例如 123.4123.4 ,要求把这个数字翻转过来,变成 4.3214.321 并输出。

输入格式

一行一个浮点数

输出格式

一行一个浮点数

输入输出样例

代码实现

#include<stdio.h>

char s[1000];
int main(void)
{
	scanf("%s",s);
	int i=0;
	for (;s[i];i++);
	for (--i;i>=0;--i) putchar(s[i]);
	puts("");
	return 0;
}

P3954 [NOIP 2017 普及组] 成绩

题目描述

牛牛最近学习了C++入门课程,这门课程的总成绩计算方法是:

总成绩=作业成绩\times 20\%+×20%+小测成绩×30\%+×30%+期末考试成绩\times 50\%×50%

牛牛想知道,这门课程自己最终能得到多少分。

输入格式

三个非负整数A,B,CA,B,C,分别表示牛牛的作业成绩、小测成绩和期末考试成绩。相邻两个数之间用一个空格隔开,三项成绩满分都是100100分。

输出格式

一个整数,即牛牛这门课程的总成绩,满分也是100100分。

输入输出样例

说明/提示

输入输出样例1说明

牛牛的作业成绩是100100分,小测成绩是100100分,期末考试成绩是8080分,总成绩是100 \times 20\%+100 \times 30\%+80 \times 50\%=20+30+40=90100×20%+100×30%+80×50%=20+30+40=90。

输入输出样例2说明

牛牛的作业成绩是6060分,小测成绩是9090分,期末考试成绩是8080分,总成绩是60 \times 20\%+90 \times 30\%+80 \times 50\%=12+27+40=7960×20%+90×30%+80×50%=12+27+40=79。

数据说明

对于30\%30%的数据,A=B=0A=B=0。

对于另外30\%30%的数据,A=B=100A=B=100。

对于100\%100%的数据,0≤A,B,C≤1000≤A,B,C≤100且A,B,CA,B,C都是1010的整数倍。

代码实现

#include<stdio.h>
#include<cmath>

int main(void)
{
	int a,b,c;
	scanf("%d%d%d",&a,&b,&c);
	printf("%d\n",a/10*2+b/10*3+c/10*5);
	return 0;
}

P5709 【深基2.习6】Apples Prologue / 苹果和虫子

题目描述

八尾勇喜欢吃苹果。她现在有 m(m\le 100)m(m≤100) 个苹果,吃完一个苹果需要花费 t(0 \le t \le100)t(0≤t≤100) 分钟,吃完一个后立刻开始吃下一个。现在时间过去了 s(s\le 10000)s(s≤10000) 分钟,请问她还有几个完整的苹果?

输入格式

输入三个非负整数表示 m 、t 和 s。

输出格式

输出一个整数表示答案。

如果你出现了 RE,不如检查一下被零除?

输入输出样例

 代码实现

#include<stdio.h>

int main(void)
{
	int m,t,s;
	scanf("%d%d%d",&m,&t,&s);
	if (t==0)
	{
		if (s==0) printf("%d\n",m);
		else puts("0");
	}
	else
	{
		int k=m-s/t;
		if (s%t>0) k--;
		if (k<=0) puts("0");
		else printf("%d\n",k);
	}
	return 0;
}

P5703 【深基2.例5】苹果采购

题目描述

现在需要采购一些苹果,每名同学都可以分到固定数量的苹果,并且已经知道了同学的数量,请问需要采购多少个苹果?

输入格式

输入两个不超过 10^9109 正整数,分别表示每人分到的数量和同学的人数。

输出格式

一个整数,表示答案。保证输入和答案都在int范围内的非负整数。

输入输出样例

 代码实现

#include<stdio.h>

int main(void)
{
	int a,b;
	scanf("%d%d",&a,&b);
	printf("%lld\n",(long long)a*b);
	return 0;
}

P5706 【深基2.例8】再分肥宅水

题目描述

现在有 t 毫升肥宅快乐水,要均分给 n 名同学。每名同学需要 2 个杯子。现在想知道每名同学可以获得多少毫升饮料(严格精确到小数点后 3 位),以及一共需要多少个杯子。输入一个实数 t 和一个整数 n,使用空格隔开。输出两个数字表示答案,使用换行隔开。

0\leq t\leq 100000≤t≤10000且不超过3位小数,1\leq n\leq 10001≤n≤1000

输入格式

输出格式

输入输出样例

 代码实现

#include<stdio.h>

int main(void)
{
	double t;
	int n;
	scanf("%lf%d",&t,&n);
	printf("%.3f\n%d\n",t/n,n*2);
	return 0;
}

P5712 【深基3.例4】Apples

题目描述

八尾勇喜欢吃苹果。她今天吃掉了 x(0\le x \le 100)x(0≤x≤100) 个苹果。英语课上学到了 apple 这个词语,想用它来造句。如果她吃了 1 个苹果,就输出 Today, I ate 1 apple.;如果她没有吃,那么就把 1 换成 0;如果她吃了不止一个苹果,别忘了 apple 这个单词后面要加上代表复数的 s。你能帮她完成这个句子吗?

输入格式

输出格式

输入输出样例

 代码实现

#include<stdio.h>

int main(void)
{
	int x;
	scanf("%d",&x);
	if (x==0)
		printf("Today, I ate 0 apple.\n");
	else if (x==1)
		printf("Today, I ate 1 apple.\n");
	else
		printf("Today, I ate %d apples.\n",x);
	return 0;
}

P5720 【深基4.例4】一尺之棰

题目描述

《庄子》中说到,“一尺之棰,日取其半,万世不竭”。第一天有一根长度为 a(a\le 10^9)a(a≤109) 的木棍,从第二天开始,每天都要将这根木棍锯掉一半(每次除 2,向下取整)。第几天的时候木棍会变为 1?

输入格式

输出格式

输入输出样例

 代码实现

#include<stdio.h>

int main(void)
{
	int a;
	scanf("%d",&a);
	for (int i=1;a>0;i++,a>>=1)
		if (a==1)
			printf("%d\n",i);
	return 0;
}

P5723 【深基4.例13】质数口袋

题目描述

小 A 有一个质数口袋,里面可以装各个质数。他从 22 开始,依次判断各个自然数是不是质数,如果是质数就会把这个数字装入口袋。口袋的负载量就是口袋里的所有数字之和。但是口袋的承重量有限,不能装得下总和超过 LL(1 \le L \le {10}^51≤L≤105)的质数。给出 LL,请问口袋里能装下几个质数?将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。

输入格式

一行一个正整数 LL。

输出格式

将这些质数从小往大输出,然后输出最多能装下的质数个数,所有数字之间有一空行。

输入输出样例

 代码实现

#include<stdio.h>

bool isprime(int val){
	for(int i=2;1ll*i*i<=val;i++)
	   if (val%i==0)
	        return false;
	return true;
}
int main(void){
	int l;
	scanf("%d",&l);
	int sum=0,cnt=0;
	for(int i=2;true;i++)
	    if (isprime(i)){
	    	if(sum+i>l)
	    	   break;
	    	sum+=i,cnt++;
	    	printf("%d\n",i);
	    	
		}
	printf("%d\n",cnt);
	return 0;	
}

P1226 【模板】快速幂||取余运算

题目描述

给你三个整数 a,b,pa,b,p,求 a^b \bmod pabmodp。

输入格式

输入只有一行三个整数,分别代表 a,b,pa,b,p。

输出格式

输出一行一个字符串 a^b mod p=s,其中 a,b,pa,b,p 分别为题目给定的值, ss 为运算结果。

输入输出样例

说明/提示

样例解释

2^{10} = 1024210=1024,1024 \bmod 9 = 71024mod9=7。

数据规模与约定

对于 100\%100% 的数据,保证 0\le a,b < 2^{31}0≤a,b<231,a+b>0a+b>0,1 \leq p \lt 2^{31}1≤p<231。

代码实现

#include<iostream>
#include<cmath>
using namespace std;

long long a,b,p;
long func (long long a,long long b){
	long long ans=1;
	while(b!=0){
		int x=b%2;
		if(x==1){
			ans=ans*a%p;
			
		}
		a=a*a%p;
		b/=2;
	}
	return ans%p;
} 
int main(){
    cin>>a>>b>>p;
    cout<<a<<"^"<<b<<" mod "<<p<<"="<<func(a,b);
	return 0;
}

P5733 【深基6.例1】自动修正

题目描述

大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。

输入格式

输出格式

输入输出样例

 代码实现

#include <iostream>
#include <cstring>
using namespace std;
char s[1000];

int main() {
	cin >> s;

	int length=strlen(s);

	for(int i = 0;i<length;i++) {

		if(s[i]>=97&&s[i]<=122) 
        {
			s[i]-=32;
		}
	}

	cout << s << endl;
}

P5743 【深基7.习8】猴子吃桃

题目描述

一只小猴买了若干个桃子。第一天他刚好吃了这些桃子的一半,又贪嘴多吃了一个;接下来的每一天它都会吃剩余的桃子的一半外加一个。第 n(n\le20)n(n≤20) 天早上起来一看,只剩下 1 个桃子了。请问小猴买了几个桃子?

输入格式

输出格式

输入输出样例

 代码实现

#include <iostream>
#include <cstring>
using namespace std;
int n;
int num[100];

int main() {
	cin >> n;
	num[n] = 1;

	for (int i = n - 1; i >= 1; i--) {

		num[i] = num[i + 1] + 1;
		num[i] *= 2;
	}

	cout << num[1] << endl;
}

P5735 【深基7.例1】距离函数

题目描述

给出平面坐标上不在一条直线上三个点坐标 (x1,y1),(x2,y2),(x3,y3),坐标值是实数,且的绝对值不超过 100.00,求围成的三角形周长。保留两位小数。

对于平面上的两个点 (x1,y1),(x2,y2),则这两个点之间的距离 dis=

输入格式

输出格式

输入输出样例

 代码实现

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;


int main() {
	double x1, x2, x3, y1, y2, y3;
	cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
	//cin >> x2 >> y2;
	//cin >> x3 >> y3;
	double ans = 0;
	ans += sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2 ));
	ans += sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3 ));
	ans += sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2 ));
	printf("%.2lf\n", ans);
	return 0;

}

P5727 【深基5.例3】冰雹猜想

题目描述

给出一个正整数 n(n\le 100)n(n≤100),然后对这个数字一直进行下面的操作:如果这个数字是奇数,那么将其乘 3 再加 1,否则除以 2。经过若干次循环后,最终都会回到 1。经过验证很大的数字(7\times10^{11}7×1011)都可以按照这样的方式比变成 1,所以被称为“冰雹猜想”。例如当 nn 是 20,变化的过程是 [20, 10, 5, 16, 8, 4, 2, 1]。

根据给定的数字,验证这个猜想,并从最后的 1 开始,倒序输出整个变化序列。

输入格式

输出格式

输入输出样例

代码实现

#include<iostream>
#include<stdio.h>
using namespace std;

int n;
int cnt;
int a[100];
int main(){
	cin>>n;
	while(n!=1){
		cnt++;
	    a[cnt]=n;
		if(n%2==1){
			n=n*3+1;
		}else{
			n=n/2;
		}
		
	}
	cout<<"1"<<" ";
		for(int i=cnt;i>=1;i--)
			cout<<a[i]<<" ";
	return 0;
} 

持续更新.....

♥♥♥每天提醒自己,自己就是个菜鸡!

♥♥♥已经看到最后啦,如果对您有帮助留下的每一个点赞、收藏、关注是对菜鸡创作的最大鼓励❀

♥♥♥有相关问题可以写在评论区,一起学习,一起进步。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器人spider

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值