算法入门的洛谷题库

数据结构

P1165 日志分析(栈的使用)

P1165 日志分析 - 洛谷

#include<vector>
#include<stack>
#include<iostream>
using namespace std;
//声明一个栈
stack<int> s;
int n;
int main(){
	cin>>n;
	int flag,w;
    //推入一个元素
	s.push(0);
	for(int i=0;i<n;i++){
		cin>>flag;
		if(flag==0){
			cin>>w;
            //取出栈顶元素(但是不退栈)
			int tmp = s.top();
			if(w>tmp){
				s.push(w);
			}else{
				s.push(tmp);
			}
		}else if(flag==1){
            //求栈的大小
			if(s.size()>1){
                //退栈
				s.pop();
			}
		}else if(flag==2){
			cout<<s.top()<<endl;
		}
	}
	return 0;
}

P3378 【模板】堆(priority的使用)

普通int类型

#include<iostream>
#include<queue>
using namespace std;
//第三个是函数 greater 大于号,前面的更大 
//priority_queue<int,vector<int>,greater<int>> que;
//less小于号,前面更小 
priority_queue<int,vector<int>,less<int>> que;
using namespace std;
int main(){
	que.push(2);
	que.push(1);
	cout<<que.top();
	return 0;
}

对结构体类型

#include<iostream>
#include<queue>
using namespace std;
typedef struct student{
	int id;
	int age;
	bool operator < (const student &s)const{
		return this->age<s.age;
	}
}student;
priority_queue<student> que;
int main(){
	student s1; s1.id=1;s1.age=28;
	student s2; s2.id=2;s2.age=20;
	que.push(s1); que.push(s2);
	cout<<que.top().age;
	return 0;
}

题目:

#include<iostream>
#include<queue>
using namespace std;
int n;
struct cmp{
	bool operator () (int a,int b){
		return a>b;
	}
};
priority_queue<int,vector<int>,struct cmp> que;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		int flag;
		cin>>flag;
		if(flag==1){
			int x;
			cin>>x;
			que.push(x);
		}else if(flag==2){
			cout<<que.top()<<endl;
		}else if(flag==3){
			que.pop();
		}
	}
	return 0;
}

B3642 二叉树的遍历(模拟非指针)

#include<iostream>
using namespace std;
int n;
typedef struct Treenode{
	int left,right;
	Treenode(int left,int right){
		this->left=left;
		this->right=right;
	}
	Treenode(){
		
	}
}Treenode;
Treenode *tree[100006];
void Preorder(int num){
	if(num!=0){
		cout<<num<<" ";
		Preorder(tree[num]->left);
		Preorder(tree[num]->right);
	}
}
void Inorder(int num){
	if(num!=0){
		Inorder(tree[num]->left);
		cout<<num<<" ";
		Inorder(tree[num]->right);
	}
}
void Afterorder(int num){
	if(num!=0){
		Afterorder(tree[num]->left);
		Afterorder(tree[num]->right);
		cout<<num<<" ";
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int left,right;
		cin>>left>>right;
		tree[i] = new Treenode();
		tree[i]->left=left; 
		tree[i]->right=right;
	}
	Preorder(1);
	cout<<endl;
	Inorder(1);
	cout<<endl;
	Afterorder(1);
	return 0;
}

P3366 【模板】最小生成树(最好使用krusal)

#include<iostream>
#include<algorithm>
//并查集 初始化为0 表示没有父节点
int arr[200005];
//边表
typedef struct node{
	int i,j,w;
	bool operator < (const node b) const{
		return this->w<b.w;
	}
}node;
node nodes[200005];
int n,m;
using namespace std;
int find(int num){
    //父节点
	if(arr[num]==num){
		return num;
	}else{
		//路径压缩 
		int res =find(arr[num]);
		arr[num]=res;
		return res;
	}
}
void merge(int a,int b){
	int parent_a = find(a);
	int parent_b = find(b);
	if(parent_a!=parent_b){
		//这里只是把b放到了a集合里
		//应该是把b的父节点放在a集合里 
		//arr[b]=parent_a;
		arr[parent_b]=parent_a;
	}
}
int fun(int a,int b){
	int parent_a = find(a);
	int parent_b = find(b);
	if(parent_a!=parent_b){
		return 0;
	}
	return 1;
}
int main(){
	cin>>n>>m;
    //初始化
	for(int i=0;i<=n;i++){
		arr[i]=i;
	}
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		node tmp;
		tmp.i=x;
		tmp.j=y;
		tmp.w =z;
		nodes[i]=tmp;
	}
    //排序
	sort(nodes+1,nodes+m+1);
	int sum=0,count=0;
    //遍历所有的边
	for(int i=1;i<=m;i++){
		node tmp = nodes[i];
		if(!fun(tmp.i,tmp.j)){
			merge(tmp.i,tmp.j);
			sum+=tmp.w;
			count++;
		}
	}
	if(count<n-1){
		cout<<"orz";
	}
	cout<<sum;
	return 0;
} 

最短路径

#include<iostream>
//可以使用INT_MAX
#include<climits>
using namespace std;
int n,m,s;
int edges[1005][1005];
int dis[1005],vis[1005];
void djstar(){
	for(int i=1;i<=n;i++){
		dis[i] = INT_MAX;
		vis[i] = 0;
	}
	vis[s]=1;
	dis[s]=0;
	for(int i=1;i<=n;i++){
		if(edges[s][i]<dis[i]){
			dis[i]=edges[s][i];
		}
	}
	for(int i=0;i<n-1;i++){
		int min=INT_MAX;
		int minI=-1;
		for(int j=1;j<=n;j++){
			if(dis[j]<min&&vis[j]==0){
				min = dis[j];
				minI=j;
			}
		}
		if(minI==-1) return;
		vis[minI] = 1;
		for(int j=1;j<=n;j++){
			if(vis[j]==0&&dis[j]>dis[minI]+edges[minI][j]){
				if(edges[minI][j]!=INT_MAX){
					dis[j]=dis[minI]+edges[minI][j];	
				}
			}
		}
	}
}
int main(){
	cin>>n>>m>>s;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			edges[i][j]=INT_MAX;
		}
	}
	for(int i=0;i<m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		if(edges[u][v]>w){
			edges[u][v]=w;
		}
	}
	djstar();
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
}

模拟

P1980 [NOIP 2013 普及组] 计数问题

第一次训练 - Virtual Judge

[P1980 NOIP 2013 普及组] 计数问题 - 洛谷

#include<iostream>
#include<vector>
#define maxsize 1e6+7
int n,x;
std::vector<int> arr(maxsize);
void count(int num){
	while(num){
		arr[num%10]++;
		num/=10;
	}
}
int main(){
	std::cin>>n>>x;
	for(int i=1;i<=n;i++){
		count(i);
	}
	std::cout<<arr[x];
	return 0;
}

P1055 [NOIP 2008 普及组] ISBN 号码(基本string运算)

[P1055 NOIP 2008 普及组] ISBN 号码 - 洛谷

#include<iostream>
#include<string>

int main(){
	std::string s;
	std::cin>>s; 
	//生成纯数字的字符串 
	std::string tmp;
	for(auto &i :s){
		if(i!='-'){
			tmp+=i;
		}
	}
	//求和 
	int res=0;
	for(int i=0;i<tmp.length()-1;i++){
		res+=(tmp[i]-'0')*(i+1);
	}
	res= res%11;
	if(res==10){
		if(s[s.length()-1]=='X'){
			std::cout<<"Right";
		}else{
			//输出s
			for(int i=0;i<s.length()-1;i++){
					std::cout<<s[i];
			} 
			std::cout<<"X";
		}
	}else{
		if(s[s.length()-1]==res+'0'){
			std::cout<<"Right";
		}else{
			//输出s
			for(int i=0;i<s.length()-1;i++){
					std::cout<<s[i];
			} 
			char c=res+'0';
			std::cout<<c;
		}
	}
	return 0;
}

基本字符串判断和运算

#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main(){
	string s ="1023456789";
	//从0开始,包括0,一共截取3个 
	string tmp = s.substr(0,3);
	cout<<tmp<<endl;
	//这个find 如果返回了npos那么就是没有找到 
	cout<<tmp.find("10");
	if(tmp.find("10")==string::npos){
		cout<<"不存在";
	}
	if(isalpha(s[0])){
		cout<<"是字母"<<endl;
	}
	if(isdigit(s[0])){
		cout<<"是数字"<<endl;
	}
	if(isupper(s[0])){
		cout<<"是大写"<<endl;
	}
	if(islower(s[0])){
		cout<<"是小写"<<endl;
	}
	return 0;
}

P5015 [NOIP 2018 普及组] 标题统计

[P5015 NOIP 2018 普及组] 标题统计 - 洛谷

第一次训练 - Virtual Judge

#include<iostream>
#include<vector>
#include<string>
#define maxsize 1e6+7
int main(){
	std::string s;
	//读入一行
	std::getline(std::cin,s); 
	int count=0;
	for(int i=0;i<s.length();i++){
		if(s[i]!=' '){
			count++;
		}
	}
	std::cout<<count;
}

排序

P1177 【模板】排序 - 洛谷

#include<iostream>
#include<vector>
#include<algorithm>
int main(){
	int n;
	std::vector<int> arr;
	std::cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		std::cin>>tmp;
		arr.push_back(tmp);
	}
	std::sort(arr.begin(),arr.end());
	for(int i=0;i<n;i++){
		std::cout<<arr[i]<<" ";
	}
	return 0;
}

//从大到小

#include<iostream>
#include<vector>
#include<algorithm>
bool cmp(int a,int b){
	return a>b;
}
int main(){
	int n;
	std::vector<int> arr;
	std::cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		std::cin>>tmp;
		arr.push_back(tmp);
	}
	std::sort(arr.begin(),arr.end(),cmp);
	for(int i=0;i<n;i++){
		std::cout<<arr[i]<<" ";
	}
	return 0;
}
快速排序(应用) sort函数
#include<iostream>
#include<algorithm>
using namespace std;
//快速排序
//1.定一个pivot,然后对数组进行一趟排序,排序完成后小于的放左边,否则放右边
//2.对左右子表,分别进行快速排序,最后等到左右子表只有一个元素的时候排序结束
int partition(int arr[],int left,int right){
	//pivot不是arr[0] 
	int pivot =arr[left];
	while(left<right){
		//while循环里一定要带left<right 
		while(left<right&&arr[right]>=pivot) right--;
		//从右边拿元素到左边 
			arr[left]=arr[right];
		while(left<right&&arr[left]<=pivot) left++;
		//从左边拿元素到右边 
			arr[right]=arr[left];
	}
	arr[left]=pivot;
	return left;
} 
void QuickSort(int arr[],int left,int right){
	if(left<right){
		int middle=partition(arr,left,right);
		for(int i=0;i<10;i++){
			cout<<arr[i]<<" ";
		} 
		cout<<endl; 
		QuickSort(arr,left,middle-1);
		QuickSort(arr,middle+1,right);
	}
}
int main(){
	int arr[]={6,8,7,9,0,1,3,2,4,5};//测试数据
	//int arr[]={49,38,65,97,76,13,27,49};//测试数据
	//int arr[]={29,18,25,47,58,12,51,10};//测试数据
	QuickSort(arr,0,9);
}
归并排序(应用)

求逆序对(mid-i+1)

#include<iostream>
using namespace std;
long long sum=0;
int arr[500007];
int tmp[500007];
int n;
void merge(int begin,int end){
	int mid = (begin+end)/2;
	int count = begin;
	//i要从begin开始 j要从mid+1开始 
	int i=begin,j=mid+1;
	for(;i<=mid&&j<=end;){
		if(arr[i]<=arr[j]){
			tmp[count++]=arr[i++];
		}else{
			//计算逆序对 
			sum+=mid-i+1;
			tmp[count++]=arr[j++];
		}
	}
	while(i<=mid){
		tmp[count++]=arr[i++];
	}
	while(j<=end){
		tmp[count++]=arr[j++];
	}
	for(int i=begin;i<=end;i++){
		arr[i]=tmp[i];
	}
}
void sort(int b,int e){
	if(b<e){
		int mid = (b+e)/2;
		sort(b,mid);
		sort(mid+1,e);
		merge(b,e);
	}
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>arr[i];
	}
	sort(0,n-1);
	cout<<sum<<endl;
	return 0;
}

数的划分

数的划分 - 洛谷 P1025 - Virtual Judge

#include <iostream>
#define maxsize 1000
int dp[maxsize][maxsize]={0};
//dp[i][j] 表示把i分成j份有多少次
int n,k;
int main() {
 	std::cin>>n>>k;
 	//将0分成0份有1种方式 初始化
 	dp[0][0]=1;
 	for(int i=1;i<=n;i++){
 		for(int j=1;j<=k;j++){
 			//分成第一份是1,第二份不是1
			 //第一份是1 dp[i-1][j-1]
			 //第一份不是1,就每个分一个1,然后再分dp[i-j][j] 
			if(i>=j){
                //一种先分一个位置是1 其他再分 dp[i-1][j-1](至少有一个1)
                //一种每个位置先分一个1,再分 dp[i-j][j](一个1都没有)
				dp[i][j] = dp[i-1][j-1] + dp[i-j][j];
			}
		 }
	 }
	 std::cout<<dp[n][k]; 
    return 0;
}

P1024 [NOIP 2001 提高组] 一元三次方程求解

[P1024 NOIP 2001 提高组] 一元三次方程求解 - 洛谷

遍历所有的解,当函数值不同号时,取平均值

#include <iostream>
#include <cmath>
using namespace std;
  double a, b, c, d;
double f(double i){
	return i*i*i*a+b*i*i+c*i+d;
}
int main() {
	cin>>a>>b>>c>>d;
	for(double i=-100.00;i<100.00;i+=0.01){
		double j=i+0.01;
		double y1=f(i);
		double y2=f(j);
		if(y1*y2<0){
			printf("%.2lf ",(i+j)/2);
		}
	}
    return 0;
}

P1421 小玉买文具(进制转换)

P1421 小玉买文具 - 洛谷

第三次训练 - Virtual Judge

#include<iostream>
using namespace std;
//全都转化为十进制做除法
int a,b;
int main(){
	cin>>a>>b;
	int sum=0;
	sum+=a*10;
	sum+=b;
	cout<<sum/19;
	return 0;
}

P6382 『MdOI R2』Car(常见字符串的识别题目)

第三次训练 - Virtual JudgeP6382 『MdOI R2』Car - 洛谷

#include<iostream>
using namespace std;
string s;
int getnum(){
	for(int i=s.length()-1;i>=0;i--){
		if(isdigit(s[i])){
			return s[i]-'0';
		}
	}
}
int main(){
	cin>>s;
    //截取字符串
	string flag = s.substr(0,3);
	if(flag=="MDA"){
		//字符传化 
		int num = getnum();
		for(int i=1;i<=5;i++){
			if(i==5){
				if(num==5||num==0){
					cout<<1<<" ";
				} else{
					cout<<0<<" ";
				}
				break;
			}
			if(num==i||num==10-i){
				cout<<1<<" ";
			}else{
				cout<<0<<" ";
			}
		}
	}else{
		for(int i=0;i<=4;i++){
			cout<<"1"<<" ";
		}
	}
	return 0;
}

P1143 进制转换

P1143 进制转换 - 洛谷

#include<iostream>
#include<string>
#include<cctype>
#include<cmath>
//一开始和最后的进制
int begin,end;
std::string s;
int main(){
	std::cin>>begin;
	std::cin>>s;
	std::cin>>end;
	//转化为十进制
	int sum=0;
    //每一位的权值 (通过权值传化为十进制)
	int level_power=0;
	for(int i=s.length()-1; i >=0;i--){
		//每一位的数码
        int num=0;
		if(std::isupper(s[i])){
			num = s[i]-'A';
			num+=10;
		}else{
			num = s[i]-'0';
		}
		int tmp = num*pow(begin,level_power);
		level_power++;
		sum+= tmp;
	} 
    //通过求余把十进制转化为其他的进制
	s="";
	if(end==10){
		std::cout<<sum;
	}else{
        //进行转化
		int stack[10000];
		int j=0;
		while(sum){
			stack[j++]=sum%end;
			//更新sum 
			sum/=end;
		}
		//最后j++到最后的这个地方并没有更新数据
		j--;
		while(j>=0){
			if(stack[j]>=10){
				int tmp = stack[j]%10;
				char c = 'A'+tmp;
				s+=c;
			}else{
				char c = '0' + stack[j];
				s+=c;
			}
			j--;
		}
		std::cout<<s;
	}
	return 0;
}

P1425 小鱼的游泳时间(时间类的转化为进制问题)

P1425 小鱼的游泳时间 - 洛谷

#include<iostream>
#include<string>
#include<cctype>
#include<cmath>
int a,b,c,d;
int main(){
	std::cin>>a>>b>>c>>d;
	//用进制 60进制 也就是全部有多少分钟 
	int num1 = a*60+b;
	int num2 = c*60+d;
	int res = num2-num1; 
	std::cout<<res/60<<" "<<res%60;
	return 0;
}

P1553 数字反转(学习一些字符串处理函数)

P1553 数字反转(升级版) - 洛谷

#include<iostream>
#include<algorithm>
using namespace std;
string s;
//删除字符串中的后置0 
void trim(string &s){
	while(s.back()=='0'&&s.length()>1){
        //后置删除    s.erase(s.begin(),3)  str.erase(0,3)
		s.pop_back();
	}
	reverse(s.begin(),s.end());
}
int main(){
	int final = 0;
	cin>>s;
	if(s[s.length()-1]=='%'){
		final=1;
		s.pop_back();
		trim(s);
		cout<<s<<"%";
	} 
	int flag_xiaoshu = s.find(".");
	if(flag_xiaoshu!=-1){
		final=1;
		//裁剪 
		string before=s.substr(0,flag_xiaoshu);
		trim(before);
		cout<<before;
		cout<<".";
		string after = s.substr(flag_xiaoshu+1,s.length()-flag_xiaoshu+1);
		trim(after);
		//这里最后也需要裁剪一下
		while(after.back()=='0'&&after.length()>1){
			after.pop_back();
		} 
		cout<<after;
	}
	int flag = s.find("/");
	if(flag!=-1){
		final=1;
		//裁剪 
		string before=s.substr(0,flag);
		trim(before);
		cout<<before;
		cout<<"/";
		string after = s.substr(flag+1,s.length()-flag+1);
		trim(after);
		//这里最后也需要裁剪一下
		while(after.back()=='0'&&after.length()>1){
			after.pop_back();
		} 
		cout<<after;
	}
	if(final==0){
		trim(s);
		cout<<s;
	}
	return 0;
}

P8651 [蓝桥杯 2017 省 B] 日期问题(格式输出)

[P8651 蓝桥杯 2017 省 B] 日期问题 - 洛谷

第二次训练 - Virtual Judge

日期类的核心

1.遍历所有的日期

2.闰年的判断

3.月份31天, 闰年2月有29天 否则28天

#include<iostream>
#include<string>
using namespace std;
string s;
int days[]={0,31,27,31,30,31,30,31,31,30,31,30,31};
int main(){
	cin>>s;
	int r_year = stoi(s.substr(0,2));
	int r_month = stoi(s.substr(3,2));
	int r_day = stoi(s.substr(6,2));
	for(int year = 1960; year<=2059;year++){
			int flag =0;
			//世纪闰年 
			if(year%400==0){
				flag =1;
				//普通闰年 
			}else if(year%4==0&&year%100!=0){
				flag =1;
			}
			if(flag == 1){
				days[2]=29;
			}else{
				days[2]=28;
			}
		for(int month=1;month<=12;month++){
			for(int day=1;day<=days[month];day++){
				if(year%100==r_year&&r_month==month&&r_day==day){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
				if(year%100==r_day&&month==r_year&&day==r_month){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
				if(year%100==r_day&&month==r_month&&day==r_year){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
			}
		}
	}
	return 0;
}

P2074 危险区域

P2074 危险区域 - 洛谷

第三次训练 - Virtual Judge

1.不是BFS而是直接计算距离

#include<iostream>
#include<cmath>
using namespace std;
int n,m,k,t;
int count =0;
int res = -1;
//计算距离
double distance(int x1,int y1,int x2,int y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main(){
	cin>>n>>m>>k>>t;
	//用正方形框柱圆圈
	for(int i=0;i<k;i++){
		int x0,y0;
		cin>>x0>>y0;
		//画正方形 
		for(int r=max(1,x0-t);r<=min(n,x0+t);r++){
			for(int c=max(1,y0-t);c<=min(n,y0+t);c++){
				if(distance(x0,y0,r,c)<=t){
					count++;
				}
			}
		}
		res=max(res,count);
		count =0;
	} 
	cout<<res;
	return 0;
}

DFS BFS搜索类

记忆化DFS

滑雪

期末最终测试 - Virtual Judge SHOI2002] 滑雪 - 洛谷

1.滑雪必须从高往下滑,所以不会有vis数组,因为不可能重新滑回来

2.当我们寻找一个最长路径的时候必须9->8->7->6是一个最长路径时,8的最长路径就已经确定了8->7->6

#include<iostream>
using namespace std;
//dfs遍历数组
int direction_x[]={-1,1,0,0};
int direction_y[]={0,0,-1,1};
int dp[107][107];
int map[107][107];
int r,c;
int res=-1;
int check(int x,int y){
	if(x<=0||x>r||y<=0||y>c){
		return 0;
	}
	return 1;
}
//返回i,j的最长路径 
int dfs(int i,int j){
    //如果当前搜索过
	if(dp[i][j]!=0){
		return dp[i][j];
	}else{
		//没搜索过 =1 开始搜索
		dp[i][j]=1;
		for(int k=0;k<4;k++){
			int x=i+direction_x[k];
			int y=j+direction_y[k];
			if(check(x,y)&&map[x][y]<map[i][j]){
				dp[i][j]=max(dp[i][j],dfs(x,y)+1);
			}
		}
	}
	return dp[i][j];
}
int main(){
	cin>>r>>c;
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			cin>>map[i][j];
		}
	}
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
            //保存所有节点的最长路径
			res = max(res,dfs(i,j));
		}
	}
	cout<<res;
	return 0;
}

普通DFS

P1162 填涂颜色

换个思路找圈子内难,但是圈子外,加上一行用DFS可以全部遍历,通过visit判断是否走完

#include<iostream>
int n,matrix[37][37],visit[37][37];
int direction_x[] = {0,0,-1,1};;
int direction_y[]= {1,-1,0,0};
void dfs(int i,int j){
	if(visit[i][j]==1||matrix[i][j]==1||i<0||i>n+1||j<0||j>n+1) return;
	else{
		visit[i][j]=1;
		for(int k=0;k<4;k++){
			dfs(i+direction_x[k],j+direction_y[k]);
		}
	}
}
int main(){
	std::cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			std::cin>>matrix[i][j];
		}
	}
	//找到第一个0
	for(int i=0;i<=n+1;i++){
		if(matrix[0][i]==0){
			dfs(0,i);
			break;
		}
	} 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(matrix[i][j]==1){
				std::cout<<matrix[i][j]<<" ";	
			}else{
				if(visit[i][j]==0){
					std::cout<<2<<" ";
				}else{
					std::cout<<0<<" ";
				}
			}
		}
		std::cout<<std::endl;
	}
	return 0;
}

P1706 全排列问题

P1706 全排列问题 - 洛谷

第三次训练 - Virtual Judge

#include<iostream>
#define maxsize 10005
#include<iomanip>
#include<vector>
using namespace std;
int n;
int visit[maxsize];
vector<int> arr;
void dfs(int i){
	if(i>n){
		for(int j=0;j<n;j++){
			cout<<setw(5)<<arr[j];
		}
		cout<<endl;
	}else{
		for(int j=1;j<=n;j++){
			//没有被选中
			if(visit[j]==0){
				visit[j]=1;
				arr.push_back(j);
				dfs(i+1);
				arr.pop_back();
				visit[j]=0;
			}
		}
	}
}
int main(){
	cin>>n;
	dfs(1);
	return 0;
}

P2089 烤鸡

第三次训练 - Virtual Judge

P2089 烤鸡 - 洛谷

1-3个数 然后全排列

#include<iostream>
#include<vector>
using namespace std;
int res=0;
int n;
int arr_res[50000][12];
vector<int> arr;
void dfs(int i){
	if(i>=10){
		int sum=0;
		for(int j=0;j<arr.size();j++){
			sum+=arr[j];
		}
		if(sum==n){
			for(int j=0;j<arr.size();j++){
				arr_res[res][j]=arr[j];
			}
			res++;
		}
	}else{
		for(int j=1;j<=3;j++){
			arr.push_back(j);
			dfs(i+1);
			arr.pop_back();
		}
	}
}
int main(){
	cin>>n;
	dfs(0);
	cout<<res<<endl;
	for(int i=0;i<res;i++){
		for(int j=0;j<10;j++){
			cout<<arr_res[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

P1219 [USACO1.5] 八皇后 Checker Challenge

第三次训练 - Virtual Judge[P1219 USACO1.5] 八皇后 Checker Challenge - 洛谷

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n;
int res = 0;
int arr_res[20][20];
vector<int> arr;
bool check(int i,int j){
	int x=0;
	for(auto num: arr){
		if(num==j){
			return false;
		}
		if(abs(x-i)==abs(j-num)){
			return false;
		}
		x++; 
	}
	return true;
}
void dfs(int i){
	if(i>=n){
        //输出前三个解
		if(res<3){
			for(int j=0;j<n;j++){
				arr_res[res][j] = arr[j];
			}
		}
		res++;
	}else{
		for(int j=0;j<n;j++){
			if(check(i,j)){
				arr.push_back(j);
				dfs(i+1);
				arr.pop_back();
			}
		}
	}
}
int main(){
	cin>>n;
	dfs(0);
	for(int i=0;i<3;i++){
		for(int j=0;j<n;j++){
            //由于前面是从0开始的,所以这里要+1
			cout<<arr_res[i][j]+1<<" ";
		}
		cout<<endl;
	}
	cout<<res;
	return 0;
}

动态规划

P1059 [NOIP 2006 普及组] 明明的随机数(去重,排序想到set)

[P1059 NOIP 2006 普及组] 明明的随机数 - 洛谷

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
vector<int> arr(1e6);
set<int> res;
int n;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>arr[i];
	}
	int cnt=0;
	for(int i=0;i<n;i++){
		res.insert(arr[i]);
	}
	cout<<res.size()<<endl;
	for(auto it : res){
		cout<<it<<" ";
	}
}

P1739 表达式括号匹配

P1739 表达式括号匹配 - 洛谷

#include<iostream>
#include<string>
using namespace std;
string s;
int main(){
	cin>>s;
	s.pop_back();
	int top=-1;
	char stack[1000000];
	int cnt=0;
	for(auto c : s){
        //左括号进栈
		if(c=='('){
			stack[++top]=c;
		}else if(c==')'){
            //栈不能为空,并且必须是(
			if(top==-1){
				cout<<"NO";
				return 0;
			}else{
				char tmp_c = stack[top--];
				if(tmp_c!='('){
					cout<<"NO";
					return 0;
				}
			}
		}
	}
    //栈为空
	if(top==-1){
		cout<<"YES";
	}else{
		cout<<"NO";
	}
	return 0;
} 

U225269 01背包问题

U225269 01背包问题 - 洛谷

#include<iostream>
#include<vector>
using namespace std;
vector<int> arr_v(1e6);
vector<int> arr_w(1e6);
int dp[5000][5000]={0},V,N;
int main(){
	cin>>V>>N;
	for(int i=1;i<=N;i++){
		cin>>arr_v[i]>>arr_w[i];
	}
	for(int i=1;i<=N;i++){
		for(int j=1;j<=V;j++){
			if(arr_v[i]<=j){
				dp[i][j] = max(dp[i-1][j],dp[i-1][j-arr_v[i]]+arr_w[i]);
			}else{
				dp[i][j]=dp[i-1][j];
			}
		}
	}
	cout<<dp[N][V];
}

P1049 [NOIP 2001 普及组] 装箱问题(01背包问题的变种)

[P1049 NOIP 2001 普及组] 装箱问题 - 洛谷

#include<iostream>
#include<vector>
using namespace std;
vector<int> arr_w(1e6);
int dp[31][20007]={0},V,N;
int main(){
	cin>>V;
	cin>>N; 
	for(int i=1;i<=N;i++){
		cin>>arr_w[i];
	}
	for(int i=1;i<=N;i++){
		for(int j=1;j<=V;j++){
			if(arr_w[i]<=j){
				dp[i][j] = max(dp[i-1][j],dp[i-1][j-arr_w[i]]+arr_w[i]);
			}else{
				dp[i][j]=dp[i-1][j];
			}
		}
	}
	cout<<V-dp[N][V];
}

P1115 最大子段和

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int n,dp[1000000];
vector<int> arr;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		cin>>tmp;
		arr.push_back(tmp);
	}
    //初始化
	dp[0]=arr[0];
	for(int i=1;i<n;i++){
        //当前值,或者前面值+1
		dp[i] = max(arr[i],dp[i-1]+arr[i]);
	}
	int max = dp[0];
	for(int i=1;i<n;i++){
		if(dp[i]>max){
			max = dp[i];
		}
	}
	cout<<max;
	return 0;
} 

P1439 【模板】最长公共子序列

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int n,dp[100000][100000];
vector<int> arr_1(10007),arr_2(10007);
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>arr_1[i];
	}
	for(int i=1;i<=n;i++){
		cin>>arr_2[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(arr_1[i]==arr_2[j]){
				dp[i][j] = dp[i-1][j-1]+1;
			}else{
				dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
			}
		}
	}
	int res = -1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			res = max(res,dp[i][j]);
		}
	}
	cout<<res;
	return 0;
} 

数据结构

P1165 日志分析(栈的使用)

P1165 日志分析 - 洛谷

#include<vector>
#include<stack>
#include<iostream>
using namespace std;
//声明一个栈
stack<int> s;
int n;
int main(){
	cin>>n;
	int flag,w;
    //推入一个元素
	s.push(0);
	for(int i=0;i<n;i++){
		cin>>flag;
		if(flag==0){
			cin>>w;
            //取出栈顶元素(但是不退栈)
			int tmp = s.top();
			if(w>tmp){
				s.push(w);
			}else{
				s.push(tmp);
			}
		}else if(flag==1){
            //求栈的大小
			if(s.size()>1){
                //退栈
				s.pop();
			}
		}else if(flag==2){
			cout<<s.top()<<endl;
		}
	}
	return 0;
}

P3378 【模板】堆(priority的使用)

普通int类型

#include<iostream>
#include<queue>
using namespace std;
//第三个是函数 greater 大于号,前面的更大 
//priority_queue<int,vector<int>,greater<int>> que;
//less小于号,前面更小 
priority_queue<int,vector<int>,less<int>> que;
using namespace std;
int main(){
	que.push(2);
	que.push(1);
	cout<<que.top();
	return 0;
}

对结构体类型

#include<iostream>
#include<queue>
using namespace std;
typedef struct student{
	int id;
	int age;
	bool operator < (const student &s)const{
		return this->age<s.age;
	}
}student;
priority_queue<student> que;
int main(){
	student s1; s1.id=1;s1.age=28;
	student s2; s2.id=2;s2.age=20;
	que.push(s1); que.push(s2);
	cout<<que.top().age;
	return 0;
}

题目:

#include<iostream>
#include<queue>
using namespace std;
int n;
struct cmp{
	bool operator () (int a,int b){
		return a>b;
	}
};
priority_queue<int,vector<int>,struct cmp> que;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		int flag;
		cin>>flag;
		if(flag==1){
			int x;
			cin>>x;
			que.push(x);
		}else if(flag==2){
			cout<<que.top()<<endl;
		}else if(flag==3){
			que.pop();
		}
	}
	return 0;
}

B3642 二叉树的遍历(模拟非指针)

#include<iostream>
using namespace std;
int n;
typedef struct Treenode{
	int left,right;
	Treenode(int left,int right){
		this->left=left;
		this->right=right;
	}
	Treenode(){
		
	}
}Treenode;
Treenode *tree[100006];
void Preorder(int num){
	if(num!=0){
		cout<<num<<" ";
		Preorder(tree[num]->left);
		Preorder(tree[num]->right);
	}
}
void Inorder(int num){
	if(num!=0){
		Inorder(tree[num]->left);
		cout<<num<<" ";
		Inorder(tree[num]->right);
	}
}
void Afterorder(int num){
	if(num!=0){
		Afterorder(tree[num]->left);
		Afterorder(tree[num]->right);
		cout<<num<<" ";
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int left,right;
		cin>>left>>right;
		tree[i] = new Treenode();
		tree[i]->left=left; 
		tree[i]->right=right;
	}
	Preorder(1);
	cout<<endl;
	Inorder(1);
	cout<<endl;
	Afterorder(1);
	return 0;
}

P3366 【模板】最小生成树(最好使用krusal)

#include<iostream>
#include<algorithm>
//并查集 初始化为0 表示没有父节点
int arr[200005];
//边表
typedef struct node{
	int i,j,w;
	bool operator < (const node b) const{
		return this->w<b.w;
	}
}node;
node nodes[200005];
int n,m;
using namespace std;
int find(int num){
    //父节点
	if(arr[num]==num){
		return num;
	}else{
		//路径压缩 
		int res =find(arr[num]);
		arr[num]=res;
		return res;
	}
}
void merge(int a,int b){
	int parent_a = find(a);
	int parent_b = find(b);
	if(parent_a!=parent_b){
		//这里只是把b放到了a集合里
		//应该是把b的父节点放在a集合里 
		//arr[b]=parent_a;
		arr[parent_b]=parent_a;
	}
}
int fun(int a,int b){
	int parent_a = find(a);
	int parent_b = find(b);
	if(parent_a!=parent_b){
		return 0;
	}
	return 1;
}
int main(){
	cin>>n>>m;
    //初始化
	for(int i=0;i<=n;i++){
		arr[i]=i;
	}
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		node tmp;
		tmp.i=x;
		tmp.j=y;
		tmp.w =z;
		nodes[i]=tmp;
	}
    //排序
	sort(nodes+1,nodes+m+1);
	int sum=0,count=0;
    //遍历所有的边
	for(int i=1;i<=m;i++){
		node tmp = nodes[i];
		if(!fun(tmp.i,tmp.j)){
			merge(tmp.i,tmp.j);
			sum+=tmp.w;
			count++;
		}
	}
	if(count<n-1){
		cout<<"orz";
	}
	cout<<sum;
	return 0;
} 

最短路径

#include<iostream>
//可以使用INT_MAX
#include<climits>
using namespace std;
int n,m,s;
int edges[1005][1005];
int dis[1005],vis[1005];
void djstar(){
	for(int i=1;i<=n;i++){
		dis[i] = INT_MAX;
		vis[i] = 0;
	}
	vis[s]=1;
	dis[s]=0;
	for(int i=1;i<=n;i++){
		if(edges[s][i]<dis[i]){
			dis[i]=edges[s][i];
		}
	}
	for(int i=0;i<n-1;i++){
		int min=INT_MAX;
		int minI=-1;
		for(int j=1;j<=n;j++){
			if(dis[j]<min&&vis[j]==0){
				min = dis[j];
				minI=j;
			}
		}
		if(minI==-1) return;
		vis[minI] = 1;
		for(int j=1;j<=n;j++){
			if(vis[j]==0&&dis[j]>dis[minI]+edges[minI][j]){
				if(edges[minI][j]!=INT_MAX){
					dis[j]=dis[minI]+edges[minI][j];	
				}
			}
		}
	}
}
int main(){
	cin>>n>>m>>s;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			edges[i][j]=INT_MAX;
		}
	}
	for(int i=0;i<m;i++){
		int u,v,w;
		cin>>u>>v>>w;
		if(edges[u][v]>w){
			edges[u][v]=w;
		}
	}
	djstar();
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
}

模拟

P1980 [NOIP 2013 普及组] 计数问题

第一次训练 - Virtual Judge

[P1980 NOIP 2013 普及组] 计数问题 - 洛谷

#include<iostream>
#include<vector>
#define maxsize 1e6+7
int n,x;
std::vector<int> arr(maxsize);
void count(int num){
	while(num){
		arr[num%10]++;
		num/=10;
	}
}
int main(){
	std::cin>>n>>x;
	for(int i=1;i<=n;i++){
		count(i);
	}
	std::cout<<arr[x];
	return 0;
}

P1055 [NOIP 2008 普及组] ISBN 号码(基本string运算)

[P1055 NOIP 2008 普及组] ISBN 号码 - 洛谷

#include<iostream>
#include<string>

int main(){
	std::string s;
	std::cin>>s; 
	//生成纯数字的字符串 
	std::string tmp;
	for(auto &i :s){
		if(i!='-'){
			tmp+=i;
		}
	}
	//求和 
	int res=0;
	for(int i=0;i<tmp.length()-1;i++){
		res+=(tmp[i]-'0')*(i+1);
	}
	res= res%11;
	if(res==10){
		if(s[s.length()-1]=='X'){
			std::cout<<"Right";
		}else{
			//输出s
			for(int i=0;i<s.length()-1;i++){
					std::cout<<s[i];
			} 
			std::cout<<"X";
		}
	}else{
		if(s[s.length()-1]==res+'0'){
			std::cout<<"Right";
		}else{
			//输出s
			for(int i=0;i<s.length()-1;i++){
					std::cout<<s[i];
			} 
			char c=res+'0';
			std::cout<<c;
		}
	}
	return 0;
}

基本字符串判断和运算

#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main(){
	string s ="1023456789";
	//从0开始,包括0,一共截取3个 
	string tmp = s.substr(0,3);
	cout<<tmp<<endl;
	//这个find 如果返回了npos那么就是没有找到 
	cout<<tmp.find("10");
	if(tmp.find("10")==string::npos){
		cout<<"不存在";
	}
	if(isalpha(s[0])){
		cout<<"是字母"<<endl;
	}
	if(isdigit(s[0])){
		cout<<"是数字"<<endl;
	}
	if(isupper(s[0])){
		cout<<"是大写"<<endl;
	}
	if(islower(s[0])){
		cout<<"是小写"<<endl;
	}
	return 0;
}

P5015 [NOIP 2018 普及组] 标题统计

[P5015 NOIP 2018 普及组] 标题统计 - 洛谷

第一次训练 - Virtual Judge

#include<iostream>
#include<vector>
#include<string>
#define maxsize 1e6+7
int main(){
	std::string s;
	//读入一行
	std::getline(std::cin,s); 
	int count=0;
	for(int i=0;i<s.length();i++){
		if(s[i]!=' '){
			count++;
		}
	}
	std::cout<<count;
}

排序

P1177 【模板】排序 - 洛谷

#include<iostream>
#include<vector>
#include<algorithm>
int main(){
	int n;
	std::vector<int> arr;
	std::cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		std::cin>>tmp;
		arr.push_back(tmp);
	}
	std::sort(arr.begin(),arr.end());
	for(int i=0;i<n;i++){
		std::cout<<arr[i]<<" ";
	}
	return 0;
}

//从大到小

#include<iostream>
#include<vector>
#include<algorithm>
bool cmp(int a,int b){
	return a>b;
}
int main(){
	int n;
	std::vector<int> arr;
	std::cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		std::cin>>tmp;
		arr.push_back(tmp);
	}
	std::sort(arr.begin(),arr.end(),cmp);
	for(int i=0;i<n;i++){
		std::cout<<arr[i]<<" ";
	}
	return 0;
}
快速排序(应用) sort函数
#include<iostream>
#include<algorithm>
using namespace std;
//快速排序
//1.定一个pivot,然后对数组进行一趟排序,排序完成后小于的放左边,否则放右边
//2.对左右子表,分别进行快速排序,最后等到左右子表只有一个元素的时候排序结束
int partition(int arr[],int left,int right){
	//pivot不是arr[0] 
	int pivot =arr[left];
	while(left<right){
		//while循环里一定要带left<right 
		while(left<right&&arr[right]>=pivot) right--;
		//从右边拿元素到左边 
			arr[left]=arr[right];
		while(left<right&&arr[left]<=pivot) left++;
		//从左边拿元素到右边 
			arr[right]=arr[left];
	}
	arr[left]=pivot;
	return left;
} 
void QuickSort(int arr[],int left,int right){
	if(left<right){
		int middle=partition(arr,left,right);
		for(int i=0;i<10;i++){
			cout<<arr[i]<<" ";
		} 
		cout<<endl; 
		QuickSort(arr,left,middle-1);
		QuickSort(arr,middle+1,right);
	}
}
int main(){
	int arr[]={6,8,7,9,0,1,3,2,4,5};//测试数据
	//int arr[]={49,38,65,97,76,13,27,49};//测试数据
	//int arr[]={29,18,25,47,58,12,51,10};//测试数据
	QuickSort(arr,0,9);
}
归并排序(应用)

求逆序对(mid-i+1)

#include<iostream>
using namespace std;
long long sum=0;
int arr[500007];
int tmp[500007];
int n;
void merge(int begin,int end){
	int mid = (begin+end)/2;
	int count = begin;
	//i要从begin开始 j要从mid+1开始 
	int i=begin,j=mid+1;
	for(;i<=mid&&j<=end;){
		if(arr[i]<=arr[j]){
			tmp[count++]=arr[i++];
		}else{
			//计算逆序对 
			sum+=mid-i+1;
			tmp[count++]=arr[j++];
		}
	}
	while(i<=mid){
		tmp[count++]=arr[i++];
	}
	while(j<=end){
		tmp[count++]=arr[j++];
	}
	for(int i=begin;i<=end;i++){
		arr[i]=tmp[i];
	}
}
void sort(int b,int e){
	if(b<e){
		int mid = (b+e)/2;
		sort(b,mid);
		sort(mid+1,e);
		merge(b,e);
	}
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>arr[i];
	}
	sort(0,n-1);
	cout<<sum<<endl;
	return 0;
}

数的划分

数的划分 - 洛谷 P1025 - Virtual Judge

#include <iostream>
#define maxsize 1000
int dp[maxsize][maxsize]={0};
//dp[i][j] 表示把i分成j份有多少次
int n,k;
int main() {
 	std::cin>>n>>k;
 	//将0分成0份有1种方式 初始化
 	dp[0][0]=1;
 	for(int i=1;i<=n;i++){
 		for(int j=1;j<=k;j++){
 			//分成第一份是1,第二份不是1
			 //第一份是1 dp[i-1][j-1]
			 //第一份不是1,就每个分一个1,然后再分dp[i-j][j] 
			if(i>=j){
                //一种先分一个位置是1 其他再分 dp[i-1][j-1](至少有一个1)
                //一种每个位置先分一个1,再分 dp[i-j][j](一个1都没有)
				dp[i][j] = dp[i-1][j-1] + dp[i-j][j];
			}
		 }
	 }
	 std::cout<<dp[n][k]; 
    return 0;
}

P1024 [NOIP 2001 提高组] 一元三次方程求解

[P1024 NOIP 2001 提高组] 一元三次方程求解 - 洛谷

遍历所有的解,当函数值不同号时,取平均值

#include <iostream>
#include <cmath>
using namespace std;
  double a, b, c, d;
double f(double i){
	return i*i*i*a+b*i*i+c*i+d;
}
int main() {
	cin>>a>>b>>c>>d;
	for(double i=-100.00;i<100.00;i+=0.01){
		double j=i+0.01;
		double y1=f(i);
		double y2=f(j);
		if(y1*y2<0){
			printf("%.2lf ",(i+j)/2);
		}
	}
    return 0;
}

P1421 小玉买文具(进制转换)

P1421 小玉买文具 - 洛谷

第三次训练 - Virtual Judge

#include<iostream>
using namespace std;
//全都转化为十进制做除法
int a,b;
int main(){
	cin>>a>>b;
	int sum=0;
	sum+=a*10;
	sum+=b;
	cout<<sum/19;
	return 0;
}

P6382 『MdOI R2』Car(常见字符串的识别题目)

第三次训练 - Virtual JudgeP6382 『MdOI R2』Car - 洛谷

#include<iostream>
using namespace std;
string s;
int getnum(){
	for(int i=s.length()-1;i>=0;i--){
		if(isdigit(s[i])){
			return s[i]-'0';
		}
	}
}
int main(){
	cin>>s;
    //截取字符串
	string flag = s.substr(0,3);
	if(flag=="MDA"){
		//字符传化 
		int num = getnum();
		for(int i=1;i<=5;i++){
			if(i==5){
				if(num==5||num==0){
					cout<<1<<" ";
				} else{
					cout<<0<<" ";
				}
				break;
			}
			if(num==i||num==10-i){
				cout<<1<<" ";
			}else{
				cout<<0<<" ";
			}
		}
	}else{
		for(int i=0;i<=4;i++){
			cout<<"1"<<" ";
		}
	}
	return 0;
}

P1143 进制转换

P1143 进制转换 - 洛谷

#include<iostream>
#include<string>
#include<cctype>
#include<cmath>
//一开始和最后的进制
int begin,end;
std::string s;
int main(){
	std::cin>>begin;
	std::cin>>s;
	std::cin>>end;
	//转化为十进制
	int sum=0;
    //每一位的权值 (通过权值传化为十进制)
	int level_power=0;
	for(int i=s.length()-1; i >=0;i--){
		//每一位的数码
        int num=0;
		if(std::isupper(s[i])){
			num = s[i]-'A';
			num+=10;
		}else{
			num = s[i]-'0';
		}
		int tmp = num*pow(begin,level_power);
		level_power++;
		sum+= tmp;
	} 
    //通过求余把十进制转化为其他的进制
	s="";
	if(end==10){
		std::cout<<sum;
	}else{
        //进行转化
		int stack[10000];
		int j=0;
		while(sum){
			stack[j++]=sum%end;
			//更新sum 
			sum/=end;
		}
		//最后j++到最后的这个地方并没有更新数据
		j--;
		while(j>=0){
			if(stack[j]>=10){
				int tmp = stack[j]%10;
				char c = 'A'+tmp;
				s+=c;
			}else{
				char c = '0' + stack[j];
				s+=c;
			}
			j--;
		}
		std::cout<<s;
	}
	return 0;
}

P1425 小鱼的游泳时间(时间类的转化为进制问题)

P1425 小鱼的游泳时间 - 洛谷

#include<iostream>
#include<string>
#include<cctype>
#include<cmath>
int a,b,c,d;
int main(){
	std::cin>>a>>b>>c>>d;
	//用进制 60进制 也就是全部有多少分钟 
	int num1 = a*60+b;
	int num2 = c*60+d;
	int res = num2-num1; 
	std::cout<<res/60<<" "<<res%60;
	return 0;
}

P1553 数字反转(学习一些字符串处理函数)

P1553 数字反转(升级版) - 洛谷

#include<iostream>
#include<algorithm>
using namespace std;
string s;
//删除字符串中的后置0 
void trim(string &s){
	while(s.back()=='0'&&s.length()>1){
        //后置删除    s.erase(s.begin(),3)  str.erase(0,3)
		s.pop_back();
	}
	reverse(s.begin(),s.end());
}
int main(){
	int final = 0;
	cin>>s;
	if(s[s.length()-1]=='%'){
		final=1;
		s.pop_back();
		trim(s);
		cout<<s<<"%";
	} 
	int flag_xiaoshu = s.find(".");
	if(flag_xiaoshu!=-1){
		final=1;
		//裁剪 
		string before=s.substr(0,flag_xiaoshu);
		trim(before);
		cout<<before;
		cout<<".";
		string after = s.substr(flag_xiaoshu+1,s.length()-flag_xiaoshu+1);
		trim(after);
		//这里最后也需要裁剪一下
		while(after.back()=='0'&&after.length()>1){
			after.pop_back();
		} 
		cout<<after;
	}
	int flag = s.find("/");
	if(flag!=-1){
		final=1;
		//裁剪 
		string before=s.substr(0,flag);
		trim(before);
		cout<<before;
		cout<<"/";
		string after = s.substr(flag+1,s.length()-flag+1);
		trim(after);
		//这里最后也需要裁剪一下
		while(after.back()=='0'&&after.length()>1){
			after.pop_back();
		} 
		cout<<after;
	}
	if(final==0){
		trim(s);
		cout<<s;
	}
	return 0;
}

P8651 [蓝桥杯 2017 省 B] 日期问题(格式输出)

[P8651 蓝桥杯 2017 省 B] 日期问题 - 洛谷

第二次训练 - Virtual Judge

日期类的核心

1.遍历所有的日期

2.闰年的判断

3.月份31天, 闰年2月有29天 否则28天

#include<iostream>
#include<string>
using namespace std;
string s;
int days[]={0,31,27,31,30,31,30,31,31,30,31,30,31};
int main(){
	cin>>s;
	int r_year = stoi(s.substr(0,2));
	int r_month = stoi(s.substr(3,2));
	int r_day = stoi(s.substr(6,2));
	for(int year = 1960; year<=2059;year++){
			int flag =0;
			//世纪闰年 
			if(year%400==0){
				flag =1;
				//普通闰年 
			}else if(year%4==0&&year%100!=0){
				flag =1;
			}
			if(flag == 1){
				days[2]=29;
			}else{
				days[2]=28;
			}
		for(int month=1;month<=12;month++){
			for(int day=1;day<=days[month];day++){
				if(year%100==r_year&&r_month==month&&r_day==day){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
				if(year%100==r_day&&month==r_year&&day==r_month){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
				if(year%100==r_day&&month==r_month&&day==r_year){
					//输出格式规定
					printf("%d-%02d-%02d\n",year,month,day); 
				}
			}
		}
	}
	return 0;
}

P2074 危险区域

P2074 危险区域 - 洛谷

第三次训练 - Virtual Judge

1.不是BFS而是直接计算距离

#include<iostream>
#include<cmath>
using namespace std;
int n,m,k,t;
int count =0;
int res = -1;
//计算距离
double distance(int x1,int y1,int x2,int y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main(){
	cin>>n>>m>>k>>t;
	//用正方形框柱圆圈
	for(int i=0;i<k;i++){
		int x0,y0;
		cin>>x0>>y0;
		//画正方形 
		for(int r=max(1,x0-t);r<=min(n,x0+t);r++){
			for(int c=max(1,y0-t);c<=min(n,y0+t);c++){
				if(distance(x0,y0,r,c)<=t){
					count++;
				}
			}
		}
		res=max(res,count);
		count =0;
	} 
	cout<<res;
	return 0;
}

DFS BFS搜索类

记忆化DFS

滑雪

期末最终测试 - Virtual Judge SHOI2002] 滑雪 - 洛谷

1.滑雪必须从高往下滑,所以不会有vis数组,因为不可能重新滑回来

2.当我们寻找一个最长路径的时候必须9->8->7->6是一个最长路径时,8的最长路径就已经确定了8->7->6

#include<iostream>
using namespace std;
//dfs遍历数组
int direction_x[]={-1,1,0,0};
int direction_y[]={0,0,-1,1};
int dp[107][107];
int map[107][107];
int r,c;
int res=-1;
int check(int x,int y){
	if(x<=0||x>r||y<=0||y>c){
		return 0;
	}
	return 1;
}
//返回i,j的最长路径 
int dfs(int i,int j){
    //如果当前搜索过
	if(dp[i][j]!=0){
		return dp[i][j];
	}else{
		//没搜索过 =1 开始搜索
		dp[i][j]=1;
		for(int k=0;k<4;k++){
			int x=i+direction_x[k];
			int y=j+direction_y[k];
			if(check(x,y)&&map[x][y]<map[i][j]){
				dp[i][j]=max(dp[i][j],dfs(x,y)+1);
			}
		}
	}
	return dp[i][j];
}
int main(){
	cin>>r>>c;
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			cin>>map[i][j];
		}
	}
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
            //保存所有节点的最长路径
			res = max(res,dfs(i,j));
		}
	}
	cout<<res;
	return 0;
}

普通DFS

P1162 填涂颜色

换个思路找圈子内难,但是圈子外,加上一行用DFS可以全部遍历,通过visit判断是否走完

#include<iostream>
int n,matrix[37][37],visit[37][37];
int direction_x[] = {0,0,-1,1};;
int direction_y[]= {1,-1,0,0};
void dfs(int i,int j){
	if(visit[i][j]==1||matrix[i][j]==1||i<0||i>n+1||j<0||j>n+1) return;
	else{
		visit[i][j]=1;
		for(int k=0;k<4;k++){
			dfs(i+direction_x[k],j+direction_y[k]);
		}
	}
}
int main(){
	std::cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			std::cin>>matrix[i][j];
		}
	}
	//找到第一个0
	for(int i=0;i<=n+1;i++){
		if(matrix[0][i]==0){
			dfs(0,i);
			break;
		}
	} 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(matrix[i][j]==1){
				std::cout<<matrix[i][j]<<" ";	
			}else{
				if(visit[i][j]==0){
					std::cout<<2<<" ";
				}else{
					std::cout<<0<<" ";
				}
			}
		}
		std::cout<<std::endl;
	}
	return 0;
}

P1706 全排列问题

P1706 全排列问题 - 洛谷

第三次训练 - Virtual Judge

#include<iostream>
#define maxsize 10005
#include<iomanip>
#include<vector>
using namespace std;
int n;
int visit[maxsize];
vector<int> arr;
void dfs(int i){
	if(i>n){
		for(int j=0;j<n;j++){
			cout<<setw(5)<<arr[j];
		}
		cout<<endl;
	}else{
		for(int j=1;j<=n;j++){
			//没有被选中
			if(visit[j]==0){
				visit[j]=1;
				arr.push_back(j);
				dfs(i+1);
				arr.pop_back();
				visit[j]=0;
			}
		}
	}
}
int main(){
	cin>>n;
	dfs(1);
	return 0;
}

P2089 烤鸡

第三次训练 - Virtual Judge

P2089 烤鸡 - 洛谷

1-3个数 然后全排列

#include<iostream>
#include<vector>
using namespace std;
int res=0;
int n;
int arr_res[50000][12];
vector<int> arr;
void dfs(int i){
	if(i>=10){
		int sum=0;
		for(int j=0;j<arr.size();j++){
			sum+=arr[j];
		}
		if(sum==n){
			for(int j=0;j<arr.size();j++){
				arr_res[res][j]=arr[j];
			}
			res++;
		}
	}else{
		for(int j=1;j<=3;j++){
			arr.push_back(j);
			dfs(i+1);
			arr.pop_back();
		}
	}
}
int main(){
	cin>>n;
	dfs(0);
	cout<<res<<endl;
	for(int i=0;i<res;i++){
		for(int j=0;j<10;j++){
			cout<<arr_res[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

P1219 [USACO1.5] 八皇后 Checker Challenge

第三次训练 - Virtual Judge[P1219 USACO1.5] 八皇后 Checker Challenge - 洛谷

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n;
int res = 0;
int arr_res[20][20];
vector<int> arr;
bool check(int i,int j){
	int x=0;
	for(auto num: arr){
		if(num==j){
			return false;
		}
		if(abs(x-i)==abs(j-num)){
			return false;
		}
		x++; 
	}
	return true;
}
void dfs(int i){
	if(i>=n){
        //输出前三个解
		if(res<3){
			for(int j=0;j<n;j++){
				arr_res[res][j] = arr[j];
			}
		}
		res++;
	}else{
		for(int j=0;j<n;j++){
			if(check(i,j)){
				arr.push_back(j);
				dfs(i+1);
				arr.pop_back();
			}
		}
	}
}
int main(){
	cin>>n;
	dfs(0);
	for(int i=0;i<3;i++){
		for(int j=0;j<n;j++){
            //由于前面是从0开始的,所以这里要+1
			cout<<arr_res[i][j]+1<<" ";
		}
		cout<<endl;
	}
	cout<<res;
	return 0;
}

动态规划

P1059 [NOIP 2006 普及组] 明明的随机数(去重,排序想到set)

[P1059 NOIP 2006 普及组] 明明的随机数 - 洛谷

#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
vector<int> arr(1e6);
set<int> res;
int n;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>arr[i];
	}
	int cnt=0;
	for(int i=0;i<n;i++){
		res.insert(arr[i]);
	}
	cout<<res.size()<<endl;
	for(auto it : res){
		cout<<it<<" ";
	}
}

P1739 表达式括号匹配

P1739 表达式括号匹配 - 洛谷

#include<iostream>
#include<string>
using namespace std;
string s;
int main(){
	cin>>s;
	s.pop_back();
	int top=-1;
	char stack[1000000];
	int cnt=0;
	for(auto c : s){
        //左括号进栈
		if(c=='('){
			stack[++top]=c;
		}else if(c==')'){
            //栈不能为空,并且必须是(
			if(top==-1){
				cout<<"NO";
				return 0;
			}else{
				char tmp_c = stack[top--];
				if(tmp_c!='('){
					cout<<"NO";
					return 0;
				}
			}
		}
	}
    //栈为空
	if(top==-1){
		cout<<"YES";
	}else{
		cout<<"NO";
	}
	return 0;
} 

U225269 01背包问题

U225269 01背包问题 - 洛谷

#include<iostream>
#include<vector>
using namespace std;
vector<int> arr_v(1e6);
vector<int> arr_w(1e6);
int dp[5000][5000]={0},V,N;
int main(){
	cin>>V>>N;
	for(int i=1;i<=N;i++){
		cin>>arr_v[i]>>arr_w[i];
	}
	for(int i=1;i<=N;i++){
		for(int j=1;j<=V;j++){
			if(arr_v[i]<=j){
				dp[i][j] = max(dp[i-1][j],dp[i-1][j-arr_v[i]]+arr_w[i]);
			}else{
				dp[i][j]=dp[i-1][j];
			}
		}
	}
	cout<<dp[N][V];
}

P1049 [NOIP 2001 普及组] 装箱问题(01背包问题的变种)

[P1049 NOIP 2001 普及组] 装箱问题 - 洛谷

#include<iostream>
#include<vector>
using namespace std;
vector<int> arr_w(1e6);
int dp[31][20007]={0},V,N;
int main(){
	cin>>V;
	cin>>N; 
	for(int i=1;i<=N;i++){
		cin>>arr_w[i];
	}
	for(int i=1;i<=N;i++){
		for(int j=1;j<=V;j++){
			if(arr_w[i]<=j){
				dp[i][j] = max(dp[i-1][j],dp[i-1][j-arr_w[i]]+arr_w[i]);
			}else{
				dp[i][j]=dp[i-1][j];
			}
		}
	}
	cout<<V-dp[N][V];
}

P1115 最大子段和

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int n,dp[1000000];
vector<int> arr;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		int tmp;
		cin>>tmp;
		arr.push_back(tmp);
	}
    //初始化
	dp[0]=arr[0];
	for(int i=1;i<n;i++){
        //当前值,或者前面值+1
		dp[i] = max(arr[i],dp[i-1]+arr[i]);
	}
	int max = dp[0];
	for(int i=1;i<n;i++){
		if(dp[i]>max){
			max = dp[i];
		}
	}
	cout<<max;
	return 0;
} 

P1439 【模板】最长公共子序列

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int n,dp[100000][100000];
vector<int> arr_1(10007),arr_2(10007);
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>arr_1[i];
	}
	for(int i=1;i<=n;i++){
		cin>>arr_2[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(arr_1[i]==arr_2[j]){
				dp[i][j] = dp[i-1][j-1]+1;
			}else{
				dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
			}
		}
	}
	int res = -1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			res = max(res,dp[i][j]);
		}
	}
	cout<<res;
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值