第三周集训总结

目录

题目总结:

1. 闰年判断

2. 洛谷 P1803 凌乱的yyy / 线段覆盖

AC代码

3. Palindromes _easy version

AC代码

4.Color the ball

AC代码

5. P3406 海底高铁

题目解读:

AC代码

小结:


题目总结:

1. 闰年判断

输入一个年份并判断是否为闰年,是闰年输出366,否则输出365。

闰年判断条件:能被4整除不能被100整除,或者能被400整除。

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n;

signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin>>n;
	if(n%400==0 || (n%4==0 && n%100!=0)) cout<<"366";
	else cout<<"365";
	return 0;
}

一道非常非常非常基础的题目,单纯为了让我重视一下c++的快读代码所以记录下来了。 

ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

 

2. 洛谷 P1803 凌乱的yyy / 线段覆盖

题目描述

现在各大 oj 上有 nn 个比赛,每个比赛的开始、结束的时间点是知道的。

yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。

所以,他想知道他最多能参加几个比赛。

由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加 22 个及以上的比赛。

输入格式

第一行是一个整数 n,接下来 n 行每行是 2 个整数 ai,bi (ai<bi),表示比赛开始、结束的时间。

输出格式

一个整数最多参加的比赛数目。

输入#1

3

0 2

2 4

1 3

输出#1

2

这是一道贪心的题目,题目本身没什么难度,关键点在于找到贪心的点。这道题目为了要多参加几场比赛,所以要贪比赛结束的时间,比赛结束的越早,剩余的时间就越多。

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;

int n;

struct Node{
	int begin,end;
}node[N];

bool cmp(Node x,Node y){
	return x.end<y.end; //按照结束时间升序排列,小的在前。
};

int main()
{
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>node[i].begin>>node[i].end;
	}
	
	sort(node,node+n,cmp);
	
	int sum=1,nn=0;
	for(int i=1;i<n;i++){
		if(node[i].begin>=node[nn].end){ //判断时间不冲突的比赛有几场
			sum++;
			nn=i;
		}
	}
	cout<<sum;
	return 0;
}

 

3. Palindromes _easy version

“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。请写一个程序判断读入的字符串是否是“回文”。

Input

输入包含多个测试实例,输入数据的第一行是一个正整数n,表示测试实例的个数,后面紧跟着是n个字符串。

Output

如果一个字符串是回文串,则输出"yes",否则输出"no".

Sample Input

4
level
abcde
noon
haha

Sample Output

yes
no
yes
no

这是一道双指针的题目,双指针分为同向指针跟异向指针,这道题用的是异向指针。

AC代码

#include <bits/stdc++.h>
using namespace std;

int n; 
string s;

int main()
{
	cin>>n;
	while(n--){
		cin>>s;

		int i=0,f=1; //将 i跟 j分别定义为字符串的开头跟结尾
		int j=s.size()-1;

		while(i<j){
			if(s[i]!=s[j]){ //每次判断是否相同
				f=0;
                break;
			}
			i++; //相同就往中心靠拢
			j--;
		}

		if(f==0) cout<<"no"<<endl;
		else cout<<"yes"<<endl;
	}
	return 0;
}

4.Color the ball

N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?

Input

每个测试实例第一行为一个整数N,(N <= 100000).

接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。当N = 0,输入结束。

Output

每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。

Sample Input

3
1 1
2 2
3 3
3
1 1
1 2
1 3
0

Sample Output

1 1 1
3 2 1

这是一道差分的题目,差分数组去记录每个气球被刷的次数。

AC代码

#include <bits/stdc++.h>
using namespace std;

int n;

int main()
{
	while(1){
		int x[100005]={0};
		cin>>n;
		if(n==0) break;
		for(int i=1;i<=n;i++){
			int a,b;
			cin>>a>>b;
			x[a]++; //差分数组
			x[b+1]--;
		}
		
		for(int i=1;i<=n;i++){
			x[i]=x[i-1]+x[i]; //将差分数组变回原数组输出
            cout<<x[i]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

5. P3406 海底高铁

题目描述

该铁路经过 N 个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的城市之间(方向不限),必须单独购买这一小段的车票。第 i 段铁路连接了城市 i 和城市 i+1(1≤i<N)。如果搭乘的比较远,需要购买多张车票。第 i 段铁路购买纸质单程票需要 Ai​ 博艾元。

虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了 IC 卡。对于第 i 段铁路,需要花 Ci 博艾元的工本费购买一张 IC 卡,然后乘坐这段铁路一次就只要扣 Bi(Bi<Ai) 元。IC 卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。每张卡都可以充值任意数额。对于第 i 段铁路的 IC 卡,无法乘坐别的铁路的车。

Uim 现在需要出差,要去 M 个城市,从城市 P1 出发分别按照 P1,P2,P3,⋯ ,PM​ 的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。

现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。

输入格式

第一行两个整数,N,M。

接下来一行,M 个数字,表示 Pi​。

接下来 N−1 行,表示第 i 段铁路的 Ai,Bi,Ci​。

输出格式

一个整数,表示最少花费

输入输出样例

输入 #1

9 10
3 1 4 1 5 9 2 6 5 3
200 100 50
300 299 100
500 200 500
345 234 123
100 50 100
600 100 1
450 400 80
2 1 10

输出 #1

6394

题目解读:

买IC卡需要额外花钱,但是买了IC卡后票价会便宜一点,所以在买票数比较少的时候,买票便宜的钱可能还不足以还上买IC卡的钱,所以IC卡不是必买的。这道题就要用差分先求出每段铁路经过了几次,再判断购买IC卡是否会更便宜。

AC代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;

int n,m;
int a[N];
int b[N];

struct Node{
	int ai,bi,ci;
}node[N];

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>a[i];
	}
	
	for(int i=1;i<n;i++){
		cin>>node[i].ai>>node[i].bi>>node[i].ci;
	}
	
	for(int i=1;i<m;i++){
		if(a[i]>a[i+1]){
			b[a[i+1]]++;
			b[a[i]]--;
		}
		else{
			b[a[i]]++;
			b[a[i+1]]--;
		}
	}
	
	for(int i=1;i<n;i++){
		b[i]=b[i]+b[i-1];
	}
	
	int sum=0;
	for(int i=1;i<n;i++){
		if(node[i].ai*b[i]>node[i].bi*b[i]+node[i].ci){
			sum+=node[i].bi*b[i]+node[i].ci;
		}
		else{
			sum+=node[i].ai*b[i];
		}
	}
	cout<<sum;
	return 0;
}

小结:

开始学习算法了,有些算法也比较难理解,遇到做不出的题开始痛苦了,加油 ! n_n !

Ps:希望再打两场Code forces能让我的名字有颜色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值