day8-蓝桥

ALGO-10. 集合运算

问题描述
给出两个整数集合A、B,求出他们的交集、并集以及B在A中的余集。
输入格式
第⼀行为⼀个整数n,表示集合A中的元素个数。
第⼆行有n个互不相同的⽤用空格隔开的整数,表示集合A中的元素。
第三行为⼀个整数m,表示集合B中的元素个数。
第四⾏行行有m个互不不相同的⽤用空格隔开的整数,表示集合B中的元素。
集合中的所有元素均为int范围内的整数,n、m<=1000。
输出格式
第⼀行行按从⼩到大的顺序输出A、B交集中的所有元素。
第⼆行行按从小到大的顺序输出A、B并集中的所有元素。
第三行按从⼩到大的顺序输出B在A中的余集中的所有元素。
样例例输⼊入
5
1 2 3 4 5
5
2 4 6 8 10
样例例输出
2 4
1 2 3 4 5 6 8 10
1 3 5
样例例输⼊入
4
1 2 3 4
3
5 6 7
样例例输出
1 2 3 4 5 6 7
1 2 3 4
只用数组进行暴力运算:

#include<iostream>
#include<algorithm>
#define max(a,b) a>=b?a:b;
#define min(a,b) a<=b?a:b;
using namespace std;

int a[1000],b[1000];
int c[2000];
int main(){
	int n,m;
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	cin>>m;
	for(int j=0;j<m;j++)
		cin>>b[j];
	sort(a,a+n);
	sort(b,b+m);
	int s=0;
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(a[i]==b[j])
				{c[s++]=b[j];
				break;
				}
		}
	}	
	for(int i=0;i<s;i++)
		cout<<c[i]<<" ";
	cout<<endl;
	int p=0;
		for(int i=0;i<n;i++)
		{
			int flag=1;
			for(int j=0;j<s;j++)
				if(a[i]==c[j])
				{
					flag=0;
					break;
				}	
			if(flag){ b[m+p]=a[i];
			p++;	}	
		}

		sort(b,b+n+m-s);
		for(int i=0;i<n+m-s;i++)
			cout<<b[i]<<" ";
		cout<<endl;
		s=0;
		for(int i=0;i<n;i++)
		{
			if(a[i]!=c[s])
			{
				cout<<a[i]<<" ";
			}
			else s++;
		}
	return 0;
}

思考:
1、利用map,第⼀一个集合的元素标记为1,第⼆二个集合的元素累加2
2.判断,值为1的为余集,有值的为交集,值为3的为并集,且map⾃带排序功能~

#include<iostream>
#include<map>
using namespace std;
int main(){
	int n,m,t;
	map<int,int>a;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>t;
		a[t]=1;//键:t,值:1 
	}
	cin>>m;
	 for(int i=0;i<n;i++)
	{
		cin>>t;
		a[t]+=2;//键:t,值:1 
	}
	for(auto it=a.begin();i!=a.end();i++)
		if(it->second==3) cout<<it->first<<" ";
	cout<<endl;
	for(auto it=a.begin();i!=a.end();i++)
		if(it->second>0) cout<<it->first<<" ";
	cout<<endl;
	for(auto it=a.begin();i!=a.end();i++)
		if(it->second==1) cout<<it->first<<" ";
	cout<<endl;
	return 0;
}

看完大佬的做法,简直了!

ALGO-11. 瓷砖铺放(递归/动态规划)


问题描述
有⼀一⻓长度为N(1<=N<=10)的地板,给定两种不不同瓷砖:⼀一种⻓长度为1,另⼀一种⻓长度为2,数⽬目不不
限。要将这个⻓长度为N的地板铺满,⼀一共有多少种不不同的铺法?
  例例如,⻓长度为4的地⾯面⼀一共有如下5种铺法:
  4=1+1+1+1
  4=2+1+1
  4=1+2+1
  4=1+1+2
  4=2+2
  编程⽤用递归的⽅方法求解上述问题。
输⼊入格式
  只有⼀一个数N,代表地板的⻓长度
输出格式
  输出⼀一个数,代表所有不不同的瓷砖铺放⽅方法的总数
样例例输⼊入
4
样例例输出
5
思考:
线性模型一般用动态规划解决
最佳解决方案a[i]都可以通过a[i-1]或者a[i-2]得出想要的结果。例如样例中长度为4,f(4)=f(3 )+1;f(4)=f(2 )+2只需要求f(2)\f(3)即可

#include<iostream>
#include<vector>

using namespace std;

int main(){
	int n;
	cin>>n;
	int count;
	vector<int> v(n+1);
	v[0]=1,v[1]=1;
	for(int i=2;i<n;i++)
	{
		v[i]=v[i-1]+v[i-2];
	 }
	 cout<<v[n]; 
	return 0;
}

ALGO-12. 幂方分解!


问题描述
任何⼀一个正整数都可以⽤用2的幂次⽅方表示。例例如:
137=27+23+20
同时约定⽅方次⽤用括号来表示,即ab 可表示为a(b)。
由此可知,137可表示为:
2(7)+2(3)+2(0)
进⼀一步:7= 22+2+20 (21⽤用2表示)
3=2+20
所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
⼜又如:
1315=210 +28 +25 +2+1
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
输⼊入格式
输⼊入包含⼀一个正整数N(N<=20000),为要求分解的整数。
输出格式
程序输出包含⼀一⾏行行字符串串,为符合约定的n的0,2表示(在表示中不不能有空格)

#include<iostream>
#include<vector>
using namespace std;
string dfs(int n){
	if(n==1) return "1";
	if(n==0) return "0";
	vector<int> v;
	int count;
	string ans;
	
	while(n){
		if(n%2==1) v.push_back(count);
		n/=2;
		count++;
	}
	for (int i = v.size() - 1; i >= 0; i--) {
		ans += "2(" + dfs(v[i]) + ")";
		if (i != 0) ans += "+";
	}
	return ans;
}
int main(){
	int n;
	cin>>n;
	string ans=dfs(n);
	for(int i=0;i<ans.size();i++)
	{
		if(ans[i+1]=='1')
			i+=3;
		cout<<ans[i];
	}
	return 0;
}

这道题就很烦

ALGO-14. 回⽂文数!

问题描述
若⼀一个数(⾸首位不不为零)从左向右读与从右向左读都⼀一样,我们就将其称之为回⽂文数。
例例如:给定⼀一个10进制数56,将56加65(即把56从右向左读),得到121是⼀一个回⽂文数。
⼜又如:对于10进制数87:
STEP1:87+78 = 165
STEP2:165+561 = 726
STEP3:726+627 = 1353
STEP4:1353+3531 = 4884
在这⾥里里的⼀一步是指进⾏行行了了⼀一次N进制的加法,上例例最少⽤用了了4步得到回⽂文数4884。
写⼀一个程序,给定⼀一个N(2<=N<=10或N=16)进制数M(其中16进制数字为0-9与A-F),求最少经
过⼏几步可以得到回⽂文数。
如果在30步以内(包含30步)不不可能得到回⽂文数,则输出“Impossible!”
输⼊入格式
两⾏行行,N与M
输出格式
如果能在30步以内得到回⽂文数,输出“STEP=xx”(不不含引号),其中xx是步数;否则输出⼀一
⾏行行”Impossible!”(不不含引号)
样例例输⼊入
9
87
样例例输出
STEP=6

#include<iostream>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int > f(vector<int> v){
	vector<int>v1(v),v2(v),ans(v.size(),0);
	reverse(v2.begin(),v2.end());//v2反置
	int temp=0;
	for(int i=v.size()-1;i>=0;i--)
	{
		ans[i]=(v1[i]+v2[i]+temp)%n;
		temp=(v1[i]+v2[i]+temp)/n;
	 } 
	if(temp>0)
		ans.insert(ans.begin(),temp);
	return ans;
} 
bool is(vector<int> v)
{
		for(int i=0;i<v.size();i++)
			if(v[i]!=v[v.size()-i-1])
				return false;
		 return true;
}

int main(){
	
	string m;
	cin>>n>>m;
	vector<int> v;
	for(int i=0;i<m.size();i++)
		if(m[i]>='0'&&m[i]<'10') v.push_back(m[i]-'0');
		else if(m[i]>='A'&&m[i]<='F') v.push_back(m[i]-'A'+10);
	int cnt=0;
//	cout<<"111";
	while(!is(v)){
		v=f(v);
		cnt++;
		if(cnt==30)
		{
			cout<<"Impossible!";
			return 0;
			}	
	}
	cout<<"STEP="<<cnt;
	
	return 0;
}

思考:
1、可以用vector的转置,vector的复制数组
2、由于有16进制(超过10了)所以用的是vector动态数组而不是string

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值