讲解
作业1
求两个正整数的乘积
## 题目描述
给你两个正整数A和B,(1<=A,B<=10^{2000})。求A与B的乘积。//高精度乘法
## 输入格式
包括一行,两个正整数A和B,(1<=A,B<=10^{2000})。
## 输出格式
一行,一个正整数表示乘积。
样例 #1
样例输入 #1
3 7
样例输出 #1
21
1 2 num1 string输入 int[] -> num1[0]='2'-'0',num1[1]='1'-'0'
*2 5 num2 -> num2[0]='4'-'0',num2[1]='2'-'0'
int ans[1000]={0}
ans[0+0]+=num1[0]*num2[0]>=10 -> ans[0+0]=ans[0]/10,ans[1]+=1
ans[1+0]+=num1[1]*num2[0]>=10 -> ans[1]/=10,ans[2]+=1
#include<iostream>
#include<cstring>
using namespace std;
string a,b;//两个乘数
int num1[2005],num2[2005],num3[4010];
int main(){
cin>>a>>b;
int n=a.length();
int m=b.length();
int len=m+n;//可能最高位数
for(int i=n-1;i>=0;--i){
num1[i]=a[n-i-1]-'0';//char 转化成整数,倒序输入
//cout<<num1[i]<<" ";
}
//cout<<endl;
for(int i=m-1;i>=0;--i){
num2[i]=b[m-i-1]-'0';
//cout<<num2[i]<<" ";
}
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
num3[i+j]+=num1[i]*num2[j];
if(num3[i+j]>=10){//进位
num3[i+j+1]+=num3[i+j]/10;
num3[i+j]=num3[i+j]%10;
}
}
}//高精度乘法
while(!num3[len]){
len--;
}//去除前导0
for(int i=len;i>=0;i--){
cout<<num3[i];
}
return 0;
}
洛谷P1007独木桥
题目背景
战争已经进入到紧要时间。你是运输小队长,正在率领运输部队向前线运送物资。运输任务像做题一样的无聊。你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在桥下欣赏士兵们。士兵们十分愤怒,因为这座独木桥十分狭窄,只能容纳 1 个人通过。假如有 2 个人相向而行在桥上相遇,那么他们 2 个人将无法绕过对方,只能有 1 个人回头下桥,让另一个人先通过。但是,可以有多个人同时呆在同一个位置。
## 题目描述
突然,你收到从指挥部发来的信息,敌军的轰炸机正朝着你所在的独木桥飞来!为了安全,你的部队必须撤下独木桥。独木桥的长度为 L,士兵们只能呆在坐标为整数的地方。所有士兵的速度都为 1 ,但一个士兵某一时刻来到了坐标为 0 或 L+1 的位置,他就离开了独木桥。
每个士兵都有一个初始面对的方向,他们会以匀速朝着这个方向行走,中途不会自己改变方向。但是,如果两个士兵面对面相遇,他们无法彼此通过对方,于是就分别转身,继续行走。转身不需要任何的时间。
由于先前的愤怒,你已不能控制你的士兵。甚至,你连每个士兵初始面对的方向都不知道。因此,你想要知道你的部队最少需要多少时间就可能全部撤离独木桥。另外,总部也在安排阻拦敌人的进攻,因此你还需要知道你的部队最多需要多少时间才能全部撤离独木桥。
## 输入格式
第一行共一个整数 L,表示独木桥的长度。桥上的坐标为 1, 2, ……, L。
第二行共一个整数 N,表示初始时留在桥上的士兵数目。
第三行共有 N 个整数,分别表示每个士兵的初始坐标。
## 输出格式
共一行,输出 2 个整数,分别表示部队撤离独木桥的最小时间和最大时间。2 个整数由一个空格符分开。
## 样例 #1
### 样例输入 #1
```
4
2
1 3
```
### 样例输出 #1
```
2 4
```
## 提示
对于 100% 的数据,满足初始时,没有两个士兵同在一个坐标,1 <= L <= 10^3,0 <= N <= 10^3,且数据保证 N <= L。
//士兵相遇的时候,可以看作两个人互相同时穿过对方继续行走
Sa0=p,Sb0=q -> <-
Sa1=Sb1=m. <- ->
Sa2=m-p+m. Sb2=q-m+L+1-m
Sa2=L+1-p,Sb2=q Sa2+Sb2=L+1-p+q. va=vb=1 总路程相同,士兵速度相同
#include<iostream>
#include<algorithm>
using namespace std;
int l,n,s[5005];//0 or l+1 leaving ok
int mini=0,maxx=0,st1=0,st2=0;
int main()
{
cin>>l>>n;
for(int i=1;i<=n;++i){
cin>>s[i];
}
for(int i=1;i<=n;++i){
mini=min(l+1-s[i],s[i]-0);//求离开时间最小值,尽量少走路
st1=max(mini,st1);//更新,用max()确保人离开
maxx=max(l+1-s[i],s[i]-0);//求离开时间最大值,尽量多走路
st2=max(maxx,st2);//更新
}
cout<<st1<<" "<<st2<<endl;
return 0;
}
洛谷P1241括号序列
## 题目描述
定义如下规则:
1. 空串是「平衡括号序列」
2. 若字符串 S 是「平衡括号序列」,那么 [S][S] 和 (S)(S) 也都是「平衡括号序列」
3. 若字符串 A 和 B 都是「平衡括号序列」,那么 ABAB(两字符串拼接起来)也是「平衡括号序列」。
例如,下面的字符串都是平衡括号序列:
`()`,`[]`,`(())`,`([])`,`()[]`,`()[()]`
而以下几个则不是:
`(`,`[`,`]`,`)(`,`())`,`([()`
现在,给定一个仅由 `(`,`)`,`[`,`]`构成的字符串 s,请你按照如下的方式给字符串中每个字符配对:
1. 从左到右扫描整个字符串。
2. 对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。
配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。
## 输入格式
输入只有一行一个字符串,表示 s。
## 输出格式
输出一行一个字符串表示你的答案。
## 样例 #1
### 样例输入 #1
```
([()
```
### 样例输出 #1
```
()[]()
```
## 样例 #2
### 样例输入 #2
```
([)
```
### 样例输出 #2
```
()[]()
```
## 提示
### 数据规模与约定
对于全部的测试点,保证 s 的长度不超过 100,且只含 `(`,`)`,`[`,`]` 四个字符。
1、找右括号‘)’,找到之后往左扫,如果先找到未被匹配过的‘(’,则配对成功;如果先找到未被匹配过的‘ [ ’,则配对失败
2、找右括号‘ ] ’,找到之后往左扫,如果先找到未被匹配过的‘ [ ’,则配对成功;如果先找到未被匹配过的‘( ’,则配对失败
3、找所有未能匹配成功的括号,逐个添加补全
#include<iostream>
#include<cstring>
using namespace std;
string s;
int vis[105];
int main()
{
cin>>s;
for(int i=0;i<s.length();++i){
if(s[i]==')'&&vis[i]==0){
for(int j=i-1;j>=0;--j){
if(s[j]=='('&&vis[j]==0){
vis[i]=1;
vis[j]=1;
break;
}
else if(s[j]=='['&&vis[j]==0)break;
}
}
else if(s[i]==']'&&vis[i]==0){
for(int j=i-1;j>=0;--j){
if(s[j]=='['&&vis[j]==0){
vis[i]=1;
vis[j]=1;
break;
}
else if(s[j]=='('&&vis[j]==0)break;
}
}
}
for(int i=0;i<s.length();++i){
if(vis[i]==0){
if(s[i]=='('||s[i]==')')cout<<"()";
else cout<<"[]";
}
else cout<<s[i];
}
cout<<endl;
//cout<<s.length();
return 0;
}
洛谷P3887 [GDOI2014]世界杯
## 题目描述
3014 年世界杯足球赛就要开始了!作为卫冕冠军中国足球队的教练,手下每位球员都是猛将,如何摆出最强的 11 人阵容也是一件幸福的烦恼事啊。
众所周知,足球阵容里的11个球员都会被分配到场上某一个特别的位置,而这些位置主要分为守门员、后卫、中场和前锋四种,其中守门员有且只有一个,后卫、中场和前锋的人数取决于你安排的足球阵型。形容足球阵型的方法由后卫开始计算至前锋,但不把守门员计算在内。例如,3-5-2 阵型是指有三个后卫、五个中场及两名前锋。由于竞争激烈,每位球员只会培养其中一种位置所需要的技能,所以他们每个人都只能胜任四个位置中的其中一种。
作为一个对球员能力了如指掌的教练,你给每个球员的综合水平进行量化。为了将阵型安排得更好,你的教练团队决定使用以下策略安排球员:首先按照顺序提出 Q 个阵型,分别代表第一阵型、第二阵型、……、第 $Q$ 阵型。然后对于每个阵型,从仍未选择的球员中选择最好的对应数量的守门员、后卫、中场和前锋。比如说,对于第一阵型,在所有球员中选择;对于第二阵型,在除了第一阵型外的所有球员中选择;对于第三阵型,在除了第一阵型和第二阵型外的所有球员中选择;以此类推。
现在 Q 个阵型都已经确定,而你需要知道的,是每个阵型的平均综合水平分别是多少。
## 输入格式
第一行有四个整数 K, D, M, F,分别表示守门员、后卫、中场和前锋供挑选的球员人数。
第二行有 K 个整数 k_i,分别表示每个守门员的综合水平值。
第三行有 D 个整数 d_i,分别表示每个后卫的综合水平值。
第四行有 M 个整数 m_i,分别表示每个中场的综合水平值。
第五行有 F 个整数 f_i,分别表示每个前锋的综合水平值。
第六行有一个整数 Q,表示教练团队提出的阵型个数。
以下 Q 行,第 i 行三个整数 A_i, B_i, C_i,由空格间隔,表示第 i 阵型是 A_i - B_i - C_i 阵型。
## 输出格式
输出 Q 行。对于第 i 种阵型,输出一个实数,表示该阵型平均综合水平的最大值,并四舍五入到小数点后 2 位。
## 样例 #1
### 样例输入 #1
```
3 10 12 4
76 60 87
78 84 84 84 81 82 72 51 77 57
85 84 62 87 88 64 81 90 80 66 88 85
65 83 63 79
2
4 5 1
4 4 2
```
### 样例输出 #1
```
85.64
78.00
```
## 提示
对于 30% 数据,K, D, M, F≤1000,Q≤10;
对于 100% 数据,1≤K, D, M, F≤10^5,0≤k[i], d[i], m[i], f[i]≤10^8,1≤Q≤K,0≤A[i], B[i], C[i]≤10,A[i]+B[i]+C[i]=10,∑A[i]≤D,∑B[i]≤M,∑C[i]≤F
题目要求综合水平最大值,那么水平高的球员优先入队->采用优先队列
存储球员数据时,优先队列可以根据比较标准自动排序,比如priority_queue<int, vector<int> , greater<int> >表示存入数据时自动从小到大排列
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,less<int> > kk,dd,mm,ff;
int k,d,m,f,k_1,d_1,m_1,f_1;
int Q;
//int d1,m1,f1;
int ts=0;
int main(){
cin>>k>>d>>m>>f;
for(int i=1;i<=k;++i){
cin>>k_1;
kk.push(k_1);
}
for(int i=1;i<=d;++i){
cin>>d_1;
dd.push(d_1);
}
for(int i=1;i<=m;++i){
cin>>m_1;
mm.push(m_1);
}
for(int i=1;i<=f;++i){
cin>>f_1;
ff.push(f_1);
}
cin>>Q;
for(int i=1;i<=Q;++i){
int d1,m1,f1;
cin>>d1>>m1>>f1;
ts+=kk.top();
kk.pop();
for(int j=1;j<=d1;++j){
ts+=dd.top();
dd.pop();
}
for(int j=1;j<=m1;++j){
ts+=mm.top();
mm.pop();
}
for(int j=1;j<=f1;++j){
ts+=ff.top();
ff.pop();
}
printf("%.2lf\n",1.0*ts/11);
ts=0;
}
return 0;
}
# [NOIP2009 普及组] 多项式输出
## 题目描述
一元 n次多项式可用如下的表达式表示:
f(x)=an^n+an−1^n−1+⋯+a1x+a0,an!=0
其中,ai*x^i称为 i 次项,ai 称为 i 次项的系数。给出一个一元多项式各项的次数和系数,请按照如下规定的格式要求输出该多项式:
1. 多项式中自变量为 x,从左到右按照次数递减顺序给出多项式。
2. 多项式中只包含系数不为 0 的项。
3. 如果多项式 n 次项系数为正,则多项式开头不出 `+` 号,如果多项式 n 次项系数为负,则多项式以 `-` 号开头。
4. 对于不是最高次的项,以 `+` 号或者 `-` 号连接此项与前一项,分别表示此项系数为正或者系数为负。紧跟一个正整数,表示此项系数的绝对值(如果一个高于 0 次的项,其系数的绝对值为 1,则无需输出 1)。如果 x 的指数大于 1,则接下来紧跟的指数部分的形式为“x^b”,其中 b 为 x 的指数;如果 x 的指数为 1,则接下来紧跟的指数部分形式为 x;如果 x 的指数为 0,则仅需输出系数即可。
5. 多项式中,多项式的开头、结尾不含多余的空格。
## 输入格式
输入共有 2 行
第一行 1 个整数,n,表示一元多项式的次数。
第二行有 n+1 个整数,其中第 i 个整数表示第 n-i+1 次项的系数,每两个整数之间用空格隔开。
## 输出格式
输出共 1 行,按题目所述格式输出多项式。
## 样例 #1
### 样例输入 #1
```
5
100 -1 1 -3 0 10
```
### 样例输出 #1
```
100x^5-x^4+x^3-3x^2+10
```
## 样例 #2
### 样例输入 #2
```
3
-50 0 0 1
```
### 样例输出 #2
```
-50x^3+1
```
## 提示
NOIP 2009 普及组 第一题
对于100%数据,0 <= n <= 100,-100 <= 系数 <= 100
---
#include<iostream>
using namespace std;
int main(){
int n,a;
cin>>n;
for(int i=n;i>=0;i--){
cin>>a;
if(a){ 判0系数
if(i!=n&&a>0)cout<<"+"; 根据正负、是否为最高此项决定加号
if(abs(a)>1||i==0)cout<<a; 输出系数(系数不为正负1或指数为0)
if(a==-1&&i)cout<<"-"; -1系数特判,常数项已特判
if(i>1)cout<<"x^"<<i; 二次及以上输出指数
if(i==1)cout<<"x"; 一次项
}
}
return 0;
}
# 【模板】快速排序
题目描述
利用快速排序算法将读入的 N 个数从小到大排序后输出。
快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL
,虽然你可以使用 sort
一遍过,但是你并没有掌握快速排序算法的精髓。)
输入格式
第 1 行为一个正整数 N,第 2 行包含 N 个空格隔开的正整数 ai,为你需要进行排序的数,数据保证了 ai 不超过 10^9。
输出格式
将给定的 N 个数从小到大输出,数之间空格隔开,行末换行且无空格。
## 样例 #1
### 样例输入 #1
```
5
4 2 4 5 1
```
### 样例输出 #1
```
1 2 4 4 5
```
## 提示
对于 20% 的数据,有 N <= 10^3;
对于 100% 的数据,有 N <= 10^5。
#include<iostream>
using namespace std;
void quicksort(int num[],int first,int end){
int i=first,j=end;
int mid=num[i+(j-i)/2];//中间值
while(i<=j){//左指针在右指针的右边就结束
while(mid>num[i])i++;//找左半部分大于中间数的
while(mid<num[j])j--;//找左半部分小于中间数的
if(i<=j)swap(num[i++],num[j--]);//先互换,然后左指针右移,右指针左移
}
//一分为二
if(first<j)quicksort(num,first,j);//左半部分再进行分割比较
if(i<end)quicksort(num,i,end);//右半部分再进行分割比较
}
int n,num[100005];
int main()
{
cin>>n;
for(int i=1;i<=n;++i)cin>>num[i];
quicksort(num,1,n);
for(int i=1;i<=n;++i)cout<<num[i]<<" ";
return 0;
}
# 【模板题】简单选择排序
题目描述
读入N个整数,利用简单选择排序法对这些数排序,输出排序后的N个数,两个数之间用空格间隔。
这里排序指的是升序。
输入格式
两行,第一行一个正整数N,表示待排序的数的个数。
第二行为N个整数。
输出格式
一行,排序后的N个数。
## 样例 #1
### 样例输入 #1
```
5
4 2 4 5 1
```
### 样例输出 #1
```
1 2 4 4 5
```
## 提示
1≤N≤103
每个数不超过10^9.
以第一个元素为基准,和后面的元素进行比较,将第一个元素之后最小的元素换上来
以第二个元素为基准,和后面的元素进行比较,将第二个元素之后最小的元素换上来
……
21 25 49 28 16 8 index=1->6
8 25 49 28 16 21 index=2->5
8 16 49 28 25 21 index=3->6
8 16 21 28 25 49. index=4->5
8 16 21 25 28 49. index=5
#include<iostream>
using namespace std;
int num[1005],n;
void sc(int a[],int len){
for(int i=1;i<len;++i){
int index=i;//index作为标记
for(int j=i+1;j<=len;++j){
if(a[index]>a[j])index=j;//更新
}
if(index!=i)swap(a[index],a[i]);//index指向的元素发生变化,则互换
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;++i)cin>>num[i];
sc(num,n);
for(int i=1;i<=n;++i)cout<<num[i]<<" ";
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术