一、基础
2、循环
最小公倍数、最大公因数:
#include<iostream>
using namespace std;
int main(){
int a,b,c;
cin>>a>>b;
int max,min;
if(a>b){
max=a;
min=b;
}else{
max=b;
min=a;
}
c=a*b;
while(c!=0){ //每次:除数变成被除数, 余数变成除数
c=max%min;
max=min;
min=c;
}
cout<<"最大公因数:"<<max<<endl;
cout<<"最小公倍数:" <<a*b/max<<endl;
return 0;
}
斐波那契数列:
#include<iostream>
using namespace std;
int fun(int a){
if( a<=2 ){
return 1;
}
return fun(a-1)+fun(a-2);
}
int main(){
int a;
cin>>a;
cout<<fun(a);
return 0;
}
n之内d出现的次数:
#include <iostream>
#include<cmath>
using namespace std;
int main() {
long long d, n, ans = 0;
cout<<"输入n和d,d为查找数:";
cin >>n>>d;// 查n以内的数字d出现的次数
long long diwei= 0;
long long gaowei = 0;
long long dangqian = 0;
long long num = 1;// 个位:1 7位:2
while (n / (long long)pow(10,num-1) != 0){
long long temp = pow(10,num-1);
diwei = n % temp;
gaowei = n / temp / 10;
dangqian = n % (temp*10) / temp;
if (dangqian < d)
ans += gaowei * temp;
else if (dangqian == d)
ans += gaowei * temp + diwei + 1;
else
ans += (gaowei + 1) * temp;
num ++;
}
cout << ans;
return 0;
}
韩信点兵
韩信有一对士兵,他想知道有多少人,他就让士兵报数,如果按照 11到 5 报数,最末一个士兵报的数为 11。
按照 11到 66 报数,最末一个士兵报的数为 5 。
按照 1 到 7 报数,最末一个士兵报的数为 4 。
最后再按 1 到11报数,最末一个士兵报的数为 10 。
请问韩信这队士兵最少有多少人?
#include<iostream>
using namespace std;
int main(){
int sum=1;
do{
if(sum%5==1&&sum%6==5&&sum%7==4&&sum%11==10){
cout<<sum;
return 0;
}
sum++;
} while(1);
}
分解质因数
将一个正整数分解质因数。 例如:输入90,90可分解为2、3、3、5四个质因数的乘积。输出从小到大的质因数乘积等式(格式如样例输出)。正整数n (1<n <100000) 。
如:输入:90,输出:90=2*3*3*5
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
cout<<n<<"=";
int x=2;
while(n){
while(n%x==0){ //除同一个素数x
cout<<x;
n/=x;
if(n>1){ //n没结束
cout<<"*";
}else{
return 0;
}
}
x++;
while(n%x!=0) x++;
}
return 0;
}
数字反转
给定一个整数n,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。(n小于100000)
#include<iostream>
using namespace std;
int main(){
int a;
cin>>a;
if(a<0){
cout<<'-';
a=-a;
}
while(a){
if(a%10!=0){
break;
}
a/=10;
}
while(a){
cout<<a%10;
a/=10;
}
}
百元买百鸡
百钱买百鸡问题。鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?输出各种鸡翁、鸡母、鸡雏的数量,依次由小到大,每种情况各占一行,每行三个数之间用一个空格隔开。(每种鸡最少1只)
例如一种情况为公鸡4只、母鸡18只、小鸡78只。 共4+18+78=100只,共100钱;
输出:4 18 78
#include<iostream>
using namespace std;
int main(){
int n=100;
for(int i=1;i<20;i++){ //公鸡只数
for(int j=1;j<=33;j++){ //母鸡只数
int a=100-5*i-3*j; //剩余钱
if(a<=0){//钱花完了
break;
}else{
int k=a*3; //小鸡只数
if(i+j+k==100){
cout<<i<<" "<<j<<" "<<k<<endl;
}
}
}
}
}
水仙花数
求100—999中的水仙花数。若三位数ABC,ABC=A^3+B^3+C^3,则称ABC为水仙花数。例如153,1^3+5^3+3^3=1+125+27=153,则153是水仙花数。
#include<iostream>
#include<cmath>
using namespace std;
int main(){
int sum=0;
for(int i=100;i<=999;i++){
int a=i/100;//百位
int b=i/10%10;//十位
int c=i%10;//个位
if(pow(a,3)+pow(b,3)+pow(c,3)==i){
cout<<i<<endl;
}
}
return 0;
}
阶乘的和
求 S=1!+2!+3!+....+n!。(对于所有数据:1≤n≤10。)
#include<iostream>
using namespace std;
int main(){
int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++){
int a=1;
for(int j=1;j<=i;j++){
a=a*j;
}
sum+=a;
}
cout<<sum;
return 0;
}
3、数组与字符串
高精度加法:
#include<iostream>
using namespace std;
string str1,str2;
int n1[300],n2[300],n3[300],len;
void f(){
for(int i=0;i<len;i++){
n3[i]+=n1[i]+n2[i];
n3[i+1]=n3[i]/10;
n3[i]%=10;
}
if(n3[len]){
cout<<n3[len];
}
for(int i=len-1;i>=0;i--){
cout<<n3[i];
}
}
int main(){
cin>>str1>>str2;
int t=str1.length()-1;
for(int i=0;i<str1.length();i++){
n1[i]=str1[t]-'0';
t--;
}
t=str2.length()-1;
for(int i=0;i<str2.length();i++){
n2[i]=str2[t]-'0';
t--;
}
if(str1.length()>=str2.length()){
len=str1.length();
f();
}else{
len=str2.length();
f();
}
}
高精度减法:
#include<iostream>
#include<cstring>
using namespace std;
void minus1(int a[],int b[],int c[],int len1,int len2){
for(int i=0;i<len1;i++){
if(a[i]-b[i]>=0){
c[i]=a[i]-b[i];
}else{
c[i]=a[i]-b[i]+10;
a[i+1]--;
}
}
}
int main(){
char ch1[105],ch2[105];
int num1[105]={0},num2[105]={0};
cin>>ch1>>ch2;
int len1=strlen(ch1),len2=strlen(ch2);
int a=0;
for(int i=len1-1;i>=0;i--){
num1[a++]=ch1[i]-'0';
}
a=0;
for(int i=len2-1;i>=0;i--){
num2[a++]=ch2[i]-'0';
}
int num3[105]={0};
int max;
if(len1>len2){ //num1长
max=len1;
minus1(num1,num2,num3,len1,len2);
}else if(len1<len2){ //num2长
max=len2;
minus1(num2,num1,num3,len2,len1);
}else{ //一样长
for(int i=len1-1;i>=0;i--){ //从高位开始,找到第一个不等的值,记为高位(最大值)
if(num1[i]!=num2[i]){
if(num1[i] > num2[i]){
max=len1;
minus1(num1,num2,num3,len1,len2);
}else{
max=len2;
minus1(num2,num1,num3,len2,len1);
}
break;
}
}
}
int flag=0; //记第一位为0
for(int i=max-1;i>=0;i--){ //从高位开始输出
if(num3[i]!=0){ //高位非零是记为 1
flag=1;
}
if(flag){ //最高位非零时
cout<<num3[i];
}
}
if(!flag){ //若整个数位为了,输出一个 0
cout<<0;
}
}
高精度乘法:
#include<bits/stdc++.h>
using namespace std;
string mul(string a,string b){
int c[10001]= {};//为了方便记录过程的结果
string ans;//最后输出的答案
//模拟竖式乘法的过程,从低位开始相乘,所以要将两个数倒置
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
//因为一共需要计算 a.size()*b.size()次;所以需要循环嵌套遍历每一个数
for(int i = 0; i < a.size(); i++)
for(int j = 0 ; j < b.size(); j++){
//然后是关键的模拟竖式运算的过程,错位相加,以及进位
c[i+j] += (a[i]-'0')*(b[j]-'0');//直接对应位数相乘
c[i+j+1] += c[i+j]/10;//有无进位
c[i+j] %= 10;//保留当前个位数
}
//两个非零因数相乘,积的位数要么是两个因数位数之和(如 9*9),
//要么是两个因数位数之和-1(如 9*1)
int len=a.size()+b.size();
//检查最高位是否为 0 ,如果为 0 ,退一位,
//while 循环可以保证即使因数是 0 也能输出正确的结果而不输出多余前导 0
while(c[len]==0&&len>0)len--;
for(int i = len; i>=0; i--)ans+=c[i]+'0';
return ans;
}
int main(){
string s1,s2;
cin>>s1>>s2;
cout<<mul(s1,s2);
return 0;
}
十进制转r进制:
法一:
#include<iostream>
using namespace std;
int main(){
char arr[105];
int n,r,pos=0;
cout<<"输入十进制 n,和需转的进制 r:";
cin>>n>>r;
while(n!= 0){
if(n%r>9){
arr[++pos]=n%r - 10 + 'A';
}else{
arr[++pos]=n%r+'0';
}
n/=r;
}
for(int i=pos;i>=1;i--){
cout<<arr[i];
}
return 0;
}
法二:
#include <iostream>
using namespace std;
int n,r;
string g(int t,string s){
if(t==0) return s;
char a=t%r+'0';
return jg(t/2,a+s); //每次往前拼接
}
int main() {
cin>>n>>r;
if(n==0){
cout<<0;
}else{
cout<<g(n,"");
}
return 0;
}
4、STL模块
vector:
#include<iostream>
#include <algorithm>
#include<vector>
using namespace std;
int main(){
// vector<int> v;
int t[]={1,2,3,4,5};
vector<int> v(t,t+5);
int n,a;
cin>>n;
// for(int i=0;i<n;i++){
// cin>>a;
// v.push_back(a);//末尾插入
// }
cout<<"返回第一个:"<<v.front()<<" 返回最后一个:"<<v.back()<<endl;
// v.pop_back();//删除最后一个元素
// v.erase(v.begin()+1;
// v.erase(v.begin()+1,v.begin() +3); //区间删除,左闭右开
// v.insert(v.begin()+ 1,100);//位置插入
// reverse(v.begin(),v.end());//翻转
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
}
5、排序
1、给出班里某门课程的成绩单,请你按成绩从高到低对成绩单排序输出,如果有相同分数则名字字典序小的在前。
输入样例:
5
Kitty 80
Hanmeimei 90
Joey 92
Tim 28Tom 90
#include<iostream>
#include<algorithm>
using namespace std;
struct student{
string name;
int score;
};
bool cmp(student a,student b){
if(a.score!=b.score){ //成绩不同
return a.score>b.score; //成绩排序
}else{
return a.name<b.name; //名字排序
}
}
int main(){
int n;
student stu[21];
cin>>n;
for(int i=0;i<n;i++){
cin>>stu[i].name>>stu[i].score;
}
sort(stu,stu+n,cmp);
for(int i=0;i<n;i++){
cout<<stu[i].name<<" "<<stu[i].score<<endl;
}
}
二、进阶:
1、深搜算法(DFS)
其过程是对每一个可能的分支路径深入到不能再深入为止,而且每一个节点只能访问一次。(一路走到头,不撞墙不回头)。
1.1图的dfs遍历
一个有 n 个结点的无向连通图,这些结点以编号:1,2,...,n进行编号,现给出结点间的连接关系。
请以结点 1 为起点,按dfs(深度优先搜索)、优先访问小编号结点的顺序遍历并输出该图。
输入: 第一行为两整数,n 和 e ,表示 nn个顶点,e 条边。( 2<=n,e<=10 )
以下 ee 行每行两个数,表示两个结点是连通的。
输出:只有一行,为按照优先访问小编号结点的dfs的结果。
#include <iostream>
using namespace std;
int n,e,sum=0;
bool f[100];
bool a[100][100];
void dfs(int t){
cout<<t<<" ";
f[t]=1;
for(int i=1;i<=n;i++){
if(a[t][i]==1 && f[i]==0){
dfs(i);
}
}
}
int main() {
cin>>n>>e;
for(int i=1;i<=e;i++){
int x,y;
cin>>x>>y;
a[x][y]=a[y][x]=1;
}
dfs(1);
return 0;
}
1.2全部排列问题
输入 n 输出 1,2,3…n 个数的全部排列。全部排列中,数字可以重复 。(1<= n <=n)
例如输入 33,输出全部排列的结果如下:111、112、113、121、122、123、131、132、133、211、212、213、221、222、223、231、232、233、311、312、313、321、322、323、331、332、333。
#include <iostream>
using namespace std;
#define ll long long
int n;
void f(string s,int k){
if(k==n){
cout<<s<<endl;
return;
}
for(int i=1;i<=n;i++){
f(s+char(i+'0'),k+1);
}
}
int main() {
string s="";
cin>>n;
f(s,0);
return 0;
}
1.3全排列的结果
从键盘读入一个整数 n,请输出 1 ∼n 中所有整数的全排列,按照由小到大输出结果,每组的 n个数之间用空格隔开。一个整数 n(1≤n≤6);
全排列的含义:从 n个不同元素中任取 m(m ≤n)个元素,按照一定的顺序排列起来,叫做从 n个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。
如当 n=3 时,全排列的结果为:
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
include <iostream>
#include <cstring>
using namespace std;
int n;
int a[20];
bool b[20]; //是否被用过
void f(int k){
if(k>n){
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(b[i]==0){
a[k]=i;
b[i]=1;
f(k+1); //回溯之后 才执行下面程序
b[i]=0;
}
}
}
int main() {
cin>>n;
f(1);
return 0;
}
1.4组合数的生成
从 1、2、3、4、5、6 这 6 个数字中任取 4 个数的组合有1 2 3 4、1 2 3 5、1 2 3 6、1 2 4 5、1 2 4 6、1 2 5 6、1 3 4 5、1 3 4 6、1 3 5 6、1 4 5 6、2 3 4 5、2 3 4 6、2 3 5 6、2 4 5 6、3 4 5 6,共 15 种。若把它们看成 4 位数,发现是递增的。
编程,输入 n 和 r,1≤r≤n≤20,按照以上顺序,输出从 n 个数字(1~n)中任取 r 个数的所有组合。
#include <iostream>
#include <cstring>
using namespace std;
int n,r;
int a[20];
bool b[20]; //是否被用过
void f(int k){
if(k>r){
for(int i=1;i<=r;i++){
printf("%d ",a[i]);
// cout<<a[i]<<" ";//不能用cin,因为cin会先存储到内存再输出
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
if(b[i]==0 && a[k-1]<i){
a[k]=i;
b[i]=1;
f(k+1); //回溯之后 才执行下面程序
b[i]=0;
}
}
}
int main() {
cin>>n>>r;
f(1);
return 0;
}
2、动态规划 参考
动态规划是分治思想的延伸,通俗一点来说就是大事化小,小事化无的艺术
1、Fibonacci
2、字符串分割
3、三角矩阵
4、路径总数
5、最小路径和
6、背包问题
7、回文串分割
8、编辑距离
9、不同子序列
2.1背包问题:
01背包
每个物品只有一个,每行代表该编号物品是否选取。
01背包两种求法:一维数组、二维数组
#include<iostream>
#include <algorithm>
using namespace std;
typedef struct{
int weight;
int value;
}Box;
int main(){
int bags,nums;
cout<<"输入总容量bags和物品数量nums:";
cin>>bags>>nums;
Box box[nums+1];
int fl[nums+1][bags+1]={},f[bags+1]={};
int goodsW,goodsV,data1,data2;
cout<<"输入"<<nums<<"组数据:重量--价值" <<endl;
for(int i=1;i<=nums;++i){
cin>>goodsW>>goodsV;
box[i].weight=goodsW;
box[i].value=goodsV;
}
//二维
for(int i=1;i<=nums;++i){ //物体编号
for(int j=1;j<=bags;++j){ //背包容量
if(j<box[i].weight){
fl[i][j]=fl[i-1][j];
}else{
data1=fl[i-1][j]; //上一行的值
data2=fl[i-1][j-box[i].weight]+box[i].value; // (总容量-当前物品大小 )的价值 + 当前物品价值
fl[i][j]=max(data1,data2);
}
}
}
cout<<"max["<<nums<<"]["<<bags<<"]:"<<fl[nums][bags];
//
//一维
// for(int i=1;i<=nums;++i){ //物体编号
// for(int j=bags;j>=box[i].weight;--j){ //背包容量
// f[j]=max(f[j], f[j-box[i].weight]+box[i].value);
// }
// }
//
// cout<<"max:"<<f[bags]<<endl;
//
}
完全背包
多重背包
2.2 八皇后问题
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
#include <iostream>
#include <cmath>
using namespace std;
int n, total=0;
int a[15];//第i行有皇后
bool f[15] ;//第i列有皇后
bool check(int m){
if(m==1) return 1;
for(int i=1;i<=m-1;i++){
if(a[i]-i==a[m]-m || a[i]+i==a[m]+m) return 0;
}
return 1;
}
void dfs(int c){
if(c>8){
cout<<"No. "<<++total<<endl;;
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
if(a[j]==i) cout<<1<<" ";
else cout<<0<<" ";
}
cout<<endl;
}
return;
}
for(int i=1;i<=8;i++){
if(f[i]==0){
f[i]=1;
a[c]=i; //c=1时 把 第一行的皇后,放在第i列
if(check(c))dfs(c+1);
f[i]=0;
}
}
}
int main(){
dfs(1);
}
三、数据结构
1、线性表
顺序表
#include<iostream>
#define Max 50
using namespace std;
struct SqList{
int data[Max];
int length;
};
int InitList(SqList &L){
// L=new SqList;
for(int i=0;i<Max;i++){
L.data[i]=0;
}
L.length=0;
return 1;
}
int InsertList(SqList &L,int index,int num){
if(L.length>=Max-1 || index<1 || index>L.length+1){
return -1;
}
for(int i=L.length;i>=index;i--){
L.data[i+1]=L.data[i];
}
L.data[index]=num;
L.length++;
return 1;
}
int DeleteList(SqList &L,int index,int &num){
if(index>=1 && index<=L.length){
num=L.data[index];
for(int i=index;i<=L.length-1;i++){
L.data[i]=L.data[i+1];
}
L.length--;
return 1;
}else{
return -1;
}
}
void LocateElem(SqList L,int num){
for(int i=0;i<L.length;i++){
if(L.data[i]==num){
cout<<num<<"的下标是"<<i<<endl;
break;
}
}
cout<<num<<"不存在"<<endl;
}
void GetElem(SqList L,int index, int &num){
num=L.data[index];
}
void IsOk(int ans){
switch(ans){
case 1:
cout<<"操作成功!"<<endl;
break;
default:
cout<<"操作失败!"<<endl;
}
}
int main(){
int ans;
SqList L;
int index,num;
//初始化 -----------------------
ans=InitList(L);
IsOk(ans);
cout<<" 0号下标不使用!"<<endl;
cout<<"当前值为:";
for(int i=0;i<Max;i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
//插入-----------------------------
cout<<"请输入插入位置index和值num①:";
cin>>index>>num;
ans=InsertList(L,index,num);
IsOk(ans);cout<<"请输入插入位置index和值num②:";
cin>>index>>num;
ans=InsertList(L,index,num);
IsOk(ans);
cout<<"请输入插入位置index和值num③:";
cin>>index>>num;
ans=InsertList(L,index,num);
IsOk(ans);
cout<<"当前值为:";
for(int i=1;i<=L.length;i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
//删除并返回--------------------------------
cout<<"输出要删除的位置index:";
cin>>index;
ans=DeleteList(L,index,num); //删除第index位的值,并返回
IsOk(ans);
cout<<"返回值是:"<<num<<endl;
cout<<"当前值为:";
for(int i=1;i<=L.length;i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
//查找index---------------------
cout<<"输出要查找的位置index:";
cin>>index;
GetElem(L,index,num); //删除第index位的值,并返回
cout<<"其下标的值为:"<<num<<endl;
//查找num是否存在-----------
cout<<"输出要查找的num:";
cin>>num;
LocateElem(L,num);
}
单链表
#include<iostream>
#define Max 50
using namespace std;
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
//初始化-带头结点
int InitList(LinkList &L){
L=new LNode;
L->next=NULL;
return 1;
}
//头插法
int HeadInsert(LinkList &L,int num){
LNode* q; //开辟节点
q=new LNode; //申请空间
//LNode *q=new LNode; 1、2行整合
q->data=num;
q->next=L->next;
L->next=q;
return 1;
}
//尾插法
int TailInsert(LinkList &L,int num){
LNode *p=L;
while(p->next){
p=p->next;
}
LNode *q;
q=new LNode;
q->data=num;
q->next=NULL;
p->next=q;
// p->next=NULL;
return 1;
}
//按值查找
int LocateElem(LinkList L,int num){
LNode *p=L->next;
int i=0;
if(p==NULL){
cout<<"空链表!!"<<endl;
return 1;
}
while(p){
i++;
if(p->data==num){
cout<<"查找成功! 它第一次出现在第"<<i<<"位!"<<endl;
return 1;
}
p=p->next;
}
cout<<"查无此数!!"<<endl;
return 1;
}
//按值删除
int delElen(LinkList &L,int num){
LNode *p=L,*q=p->next;
if(p->next==NULL){
cout<<"空链表!!"<<endl;
return 1;
}
// q=p->next;
while(q){
if(q->data==num){
p->next=q->next;
q->next==NULL;
delete q;
break;
}else{
p=q;
q=q->next;
}
}
}
//按位删除
int delElen2(LinkList &L,int num){
LNode *p=L;
if(p->next==NULL){
cout<<"空链表!!"<<endl;
return 1;
}
int j=0;
while(p->next && num>j){
p=p->next;
j++;
}
LNode *q=p->next;
p->next=p->next->next;
delete q;
return 1;
}
//遍历
void Check(LinkList L){
LNode *p;
p=L->next;
cout<<"当前值为:";
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void IsOk(int ans){
switch(ans){
case 1:
cout<<"操作成功!"<<endl;
break;
default:
cout<<"操作失败!"<<endl;
}
}
int main(){
int ans;
LinkList L;
int index,num;
//初始化 -----------------------
ans=InitList(L);
IsOk(ans);
//插入---------------
cout<<"用头插法插入一个元素num1:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num2:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num3:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num3:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
Check(L);
//按值查找
int num4;
cout<<"输入要查找的值num4:";
cin>>num4;
LocateElem(L,num4);
//按值删除
int num5;
cout<<"输入要删除的值num5:";
cin>>num5;
delElen(L,num5);
Check(L);
//按位删除
int num6;
cout<<"输入要删除的位置num6 (下标从0位开始):";
cin>>num6;
delElen2(L,num6);
Check(L);
int num7;
cout<<"用尾插法插入一个元素num7:";
cin>>num7;
ans=TailInsert(L,num7);
IsOk(ans);
Check(L);
return 0;
}
双链表
#include<iostream>
#define Max 50
using namespace std;
typedef struct LNode{
int data;
struct LNode *next;
struct LNode *prior;
}LNode,*LinkList;
int InitList(LinkList &L){ //带头结点
L=new LNode;
L->next=NULL;
return 1;
}
//头插法
int HeadInsert(LinkList &L,int num){
LNode *q=new LNode; //开辟节点,申请空间
q->data=num;
q->next=L->next;
L->next=q;
q->prior=L;
return 1;
}
//按值删除
int delElen(LinkList &L,int num){
LNode *p=L;
if(p->next==NULL){
cout<<"空链表!!"<<endl;
return 1;
}
LNode *q;
while(p->next){
q=p->next;
if(q->data==num){
q->next->prior=p;
p->next=q->next;
delete q;
return 1;
}
p=q;
}
}
//按位删除
int delElen2(LinkList &L,int num){
LNode *p=L;
if(p->next==NULL){
cout<<"空链表!!"<<endl;
return 1;
}
int j=0;
while(p->next && j<num){ //找到删除位的前一位
p=p->next;
j++;
}
LNode *q=p->next; //q指向删除位
if(q->next){ //删除位是否为尾指针
q->next->prior=q->prior;
q->prior->next=q->next;
}else{
p->next=NULL;
}
delete q;
return 1;
}
//遍历
void Check(LinkList L){
LNode *p=L;
cout<<"当前值为:";
while(p->next){
p=p->next;
cout<<p->data<<" ";
}
cout<<endl;
}
void IsOk(int ans){
switch(ans){
case 1:
cout<<"操作成功!"<<endl;
break;
default:
cout<<"操作失败!"<<endl;
}
}
int main(){
int ans;
LinkList L;
int index,num;
//初始化 -----------------------
ans=InitList(L);
IsOk(ans);
//插入---------------
cout<<"用头插法插入一个元素num1:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num2:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num3:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
cout<<"用头插法插入一个元素num3:";
cin>>num;
ans=HeadInsert(L,num);
IsOk(ans);
Check(L);
//按值删除
int num5;
cout<<"输入要删除的值num5:";
cin>>num5;
delElen(L,num5);
Check(L);
//按位删除
int num6;
cout<<"输入要删除的位置num6 (下标从0位开始):";
cin>>num6;
delElen2(L,num6);
Check(L);
return 0;
}
四、信奥
1、[CSP-J 2022] 解密
ios::sync_with_stdio(false);
而这段语句可以来打消iostream的输入 输出缓存,可以节省许多时间,使效率与scanf与printf相差无几,
还有应注意的是scanf与printf使用的头文件应是stdio.h而不是 iostream。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int k;
long long n,d,e;
ios::sync_with_stdio(false); //不加30分,加了60分
cin>>k;
for(int i=1;i<=k;i++)
{
cin>>n>>d>>e;
long long m=n-e*d+2;
bool flag=false;
for(long long p=1;p<=5e8;p++)
{
long long q=m-p;
if(p*q == n)
{
cout<<p<<" "<<q<<endl;
flag = true;
break;
}
}
if(flag == false) cout<<"NO"<<endl;
}
return 0;
}