Y1课程笔记:第一课时(语法补充)

知识点一:宏定义

1.将这些代码封装直接使用,大幅增加编写代码的速度,以节省出更多的时间
用于思考。

2.更容易DBUG

个人模板整理↓

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define ull unsigned long long
#define ll long long
#define pb push_back
#define mk make pair
#define _rep(i,a,b) for(int i=(a):i<=(b);i++)
#define sz(x) (x.size())

知识点二:快读快写

注意事项:

1.输入输出的数据过大时可以使用
2.字符串类型输入输出无法使用快读快写
3.输入输出方式要对应,cin 对应 cout,scanf 对应 printf,快读对应快写
4.不使用 cin 和 cout 时不要关同步,否则程序输出会出现问题

原理:将数字输入过程转化为一个字符一个字符输入的过程,输入完毕后转换为数字。

题目&代码模板:

A+B快速版

时间限制:2秒        内存限制:128M

题目描述

给定 n 对数 a,b ,求出所有的 a+b 。

输入描述

第一行输入 n

接下来 n 行每行有两个整数 ,a,b

输出描述

输出 n 行,n 对 a+b 的结果

输入样例

2
1 1
2 2

输出样例

2
4

数据范围
1<=n<=5×10^6,1<=a,b<=10^9

解题思路​

题目本身很​简单,但n的范围为5×10^6 ,普通的输入输出一定会超时,因此考虑快读快写

AC代码

#include<bits/stdc++.h>
using namespace std;
template<typename T>
void read(T& x){
	x=0;
	char ch=getchar();
	long long f=1;
	while(!isdigit(ch)){
		if(ch=='-'){//处理负数
			f*=-1;
		}
		ch=getchar(); 
	}
	while(isdigit(ch)){
			x=x*10+ch-48;//字符转数字
			ch=getchar();
		}
	x*=f;                                         
}
template<typename T,typename... Args>//不定参数,可输入多个参数
void read(T& first,Args&...args){
	read(first);
	read(args...);
}
template<typename T>
void write(T arg){
	T x=arg;
	if(x<0){
		putchar('-');//承接上文
		x=-x;
	}
	if(x>9){
		write(x/10);//递归输出
	}
	putchar(x%10+'0');
}
template<typename T,typename... Ts>
void write(T arg,Ts... args){
	write(arg);
	if(sizeof...(args)!=0){
		putchar(' ');
		write(args...);
	}
}
int n;
long long ans;
int main(){
    read(n);
	long long x,y;
	for(int i=1;i<=n;i++){
	    read(x,y);
        write(x+y);
	    putchar('\n');
	}
}

知识点三:STL补充

1.优先队列

先上题目↓

合并果子

时间限制:1秒        内存限制:128M

题目描述

        在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。          因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。          例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。 

输入描述

        输入包括两行,第一行是一个整数n(1< =n< =10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1< =ai< =20000)是第i种果子的数目。 

输出描述

        输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。 

样例

输入

3 
1 2 9 

输出

15

提示

对于30%的数据,保证有n< =1000:  对于50%的数据,保证有n< =5000;  对于全部的数据,保证有n< =10000。 

解题思路

由题目可以推出优先合并最小的两堆果子费力最小,因此可以考虑优先队列(注意要用小根堆),每次先选出最小的两堆果子合并,将合并耗费的体力即加入答案又压入队列,直到队列内只剩1个数此时输出答案。

AC代码

#include<bits/stdc++.h>
using namespace std;
long long n,a[40005],ans;
priority_queue<int,vector<int>,greater<int> >q;
int main(){
	cin>>n;
	long long c;
	for(int i=1;i<=n;i++){
	    cin>>c;
	    q.push(c);
	}
	long long cnt=0;
    while(q.size()>1){
        cnt=0;
        ans+=q.top();
        cnt+=q.top();
        q.pop();
        ans+=q.top();
        cnt+=q.top();
        q.pop();
        q.push(cnt);
    }
	cout<<ans;
}

2.map

先上题目↓

分类

时间限制:1秒        内存限制:128M

题目描述

仓库里面堆积着很多的货物。小可放假归来,发现仓库里多了许多的货物。

小可作为仓库管理员,需要对新多出来的货物进行分类整理。但是这段时间多出来的货物太多了,你能帮小可整理一下吗?

输入描述

第一行一个正整数T(1≤ T≤ 10),代表有T组数据。

对于每组数据,第一行有一个正整数n,代表有n条入库记录。

接下来有n行入库记录。

每个入库记录由字符串a,b和一个正整数m(1≤ m≤ 100)组成,a是货物名,b是货物来源,m是数量。这两个字符串的长度都不长于80。

输出描述

请输出合并整理后格式正确的货物统计表。格式为:

把货物按照来源地分类,来源地按照字典序排序输出。每个来源地都有下级分类。

每个来源地下级分类中,每一行输出三个空格,一个|,四个-,用来保持缩进。子分类中,将来源地是此来源地的货物按照字典序排序,每个货物后面有一个括号,里面写货物的总数量。

具体格式参考样例

样例

输入

1
5
pencil shandong 3
eraser guangdong 1
water sichuan 1
eraser guangdong 3
water guangdong 1

输出

guangdong
   |----eraser(4)
   |----water(1)
shandong
   |----pencil(3)
sichuan
   |----water(1)

解题思路

本题有三种信息要记录,按优先级从高到低排列为:货物名,货物来源,数量。

同时,从答案的层次来看,用map套map是个不错的选择。

有了这样的思路,保存、整理、输出都很简单了,详见注释

AC代码

#include<bits/stdc++.h>
using namespace std;
map<string,map<string,int> >ma;
int n,m,t;
string a,b,tmp;
int main(){
    cin>>t;
    while(t--){//多组输入↓
    cin>>n;
	map<string,map<string,int> >::iterator it;
    for(int i=1;i<=n;i++){
        cin>>a>>b;
        cin>>m;
        ma[b][a]+=m;
    }
    for(it=ma.begin();it!=ma.end();it++){//外层迭代器遍历产地
    	map<string,int>::iterator itt;
    	cout<<it->first<<'\n';
    	for(itt=(it->second).begin();itt!=(it->second).end();itt++){//内层迭代器遍历品名并输出数量
        	cout<<"   |----"<<itt->first<<'('<<itt->second<<')'<<'\n';
    	}
	}
	ma.clear();//记得重置↑
	cout<<'\n';
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值