c++经典例题

一、基础

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 28 

Tom 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值