基础算法(一)#蓝桥杯

基础算法(一)#蓝桥杯_第1张图片

文章目录

    • 1、模拟
      • 1.1、DNA序列修正
      • 1.2、无尽的石头
    • 2、递归
      • 2.1、带备忘录的斐波那契数列
      • 2.2、数的计算
    • 3、进制转换
      • 3.1、进制转换模板
      • 3.2、Alice和Bob的爱恨情仇
    • 4、前缀和
      • 4.1、前缀和模板
      • 4.2、区间次方和
      • 4.3、小郑的蓝桥平衡串
      • 4.4、大石头的搬运工
      • 4.5、最大数组和
      • 4.6、四元组问题**
    • 5、差分
      • 5.1、区间更新(一维差分)
      • 5.2、肖恩的投球游戏加强版
      • 5.4、泡澡
    • 6、离散化
      • 6.1、离散化举例
    • 7、贪心
      • 7.1、谈判(优先队列)
      • 7.2、纪念品分组(双指针)
      • 7.3、分糖果
      • 7.4、珠宝的最大交替和
      • 7.5、小蓝的礼物
      • 7.6、四个瓷瓶的神秘游戏**
      • 7.7、鸡哥的购物挑战
      • 7.8、冒险者公会
      • 7.9、明日方舟大作战

1、模拟

1.1、DNA序列修正

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int main(){
	IOS;
	int N;cin>>N;
	string s,t;
	cin>>s>>t;
	for(int i=0;i<N;i++){
		switch (s[i]) {
		case 'A':
			s[i]='T';
			break;
		case 'T':
			s[i]='A';
			break;
		case 'C':
			s[i]='G';
			break;
		case 'G':
			s[i]='C';
			break;
		}
	}
	int ans=0;
	for(int i=0;i<N;i++){
		if(s[i]==t[i])continue;
		for(int j=i+1;j<N;j++){
			if(t[j]==s[i]&&t[i]==s[j]){
				//一次操作两个正确位置
				swap(t[i],t[j]);
				break;
			}
		}
		//不能一次操作两个的话,那么只能操作一次,直接++就可以了
		//因为只需要记录交换次数就行了,所以并不是必须交换的
		ans++;
	}
	cout<<ans<<'\n';
	return 0;
}

1.2、无尽的石头

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int N = 1000000;
vector<int> a(N+1,-1);
int sm(int x){
	int s=0;
	while(x){
		s+=(x%10);
		x/=10;
	}
	return s;
}
int main(){
	IOS;
	int t;cin>>t;
	a[1]=0;
	for(int i=1;i<=N;i++){
		if(a[i]==-1)continue;
		int x=i+sm(i);
		if(x>N)break;//大于1e6的话就不再查询了
		a[x]=a[i]+1;//a[i+sm(i)]=a[i]+1
	}
	while(t--){
		int n;cin>>n;
		cout<<a[n]<<"\n";
	}
	return 0;
}

2、递归

2.1、带备忘录的斐波那契数列

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
using ll = long long;
const int N=1e5+9;
const ll p=1e9+7;
//备忘录
ll dp[N];
ll fib(int n){
	if(dp[n])return dp[n];
	if(n<=2)return 1;
	return dp[n]=(fib(n-1)+fib(n-2))%p;
}
int main(){
	IOS;
	int n;cin>>n;
	for(int i=600;i<=n;i++)cout<<fib(i)<<"\n";
	return 0;
}

2.2、数的计算

#include 
using namespace std;
int a[10001];
int dfs(int dep){
  int res=1;
  for(int i=1;i<=a[dep-1]/2;i++){
    a[dep]=i;//计算每一层的个数
    res+=dfs(dep+1);//将每一层的个数累加
  }
  return res;//返回的是每一层的个数
}
int main()
{
  int n;cin>>n;
  a[1]=n;//第一层是 6
  cout<<dfs(2)<<"\n";
  return 0;
}

3、进制转换

3.1、进制转换模板

#include
using namespace std;
char ch[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
using ll = long long;
const int N=32;
int a[N];
int main() {
	int T;cin>>T;
	while(T--){
		int n,m;cin>>n>>m;
		string s;cin>>s;
		int len=s.size();
		for(int i=0;i<len;i++){
			if(s[i]>='0'&&s[i]<='9'){
				a[i]=s[i]-'0';
			}else{
				a[i]=s[i]-'A'+10;
			}
		}
		//any -> 10进制
		ll x=0;
		for(int i=0;i<len;i++){
			x=x*n+a[i];
		}
		//10进制 -> any
		string ans;
		while(x){
			ans+=ch[x%m];
			x/=m;
		}
		reverse(ans.begin(),ans.end());
		cout<<ans<<"\n";
	}
	return 0;
}

3.2、Alice和Bob的爱恨情仇

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
// k 是奇数,每次取 k^m, m >= 0
// 假设只有一堆小饼干,有 x 个小饼干,先手胜还是输呢?
// k^m 是奇数,又因为 k^m 可以等于 1
// 如果 x 是奇数,无论后手怎么取,我先手永远取 1,等于说在我先手操作之后,小饼干的数量永远是偶数
// 而 0 是偶数
// 所以先手必胜
// 如果 x 是偶数,无论先手怎么取,我后手永远取 1,同理,后手必胜
// 回到原问题
// 设一共有 p 个小饼干(不管有多少堆)
// 如果 p 是奇数,先手永远取 1,先手必胜
// 如果 p 是偶数,后手永远取 1,后手必胜
int main(){
	IOS;
	int n,k;cin>>n>>k;
	int ans=0;
	for(int i=1;i<=n;i++){
		int num;cin>>num;
		ans+=num;
	}
	if(ans%2==0)cout<<"Bob"<<"\n";
	else cout<<"Alice"<<"\n";
	return 0;
}

4、前缀和

4.1、前缀和模板

#include
using namespace std;
//(前缀和)前缀和只适用于静态数组的情况,即进行区间查询;
//(差分)如果实现先区间修改,再区间查询就可以使用差分数组;
//(树状数组和线段树)如果需要一边修改,一边查询就需要使用树状数组或线段树
const int N = 10001;
int prefix[N],a[N];
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		prefix[i]=prefix[i-1]+a[i];
	}
	int l,r;
	cin>>l>>r;
	//求区间和 sum(l,r)=prefix[r]-prefix[l-1]
	int sum;sum=prefix[r]-prefix[l-1];
	cout<<sum<<"\n";
	return 0;		
}		 

4.2、区间次方和

#include
using namespace std;
const long long N = 1e5+9;
const long long P = 1e9+7;
long long prefix[6][N],a[6][N];
int main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[1][i];
	}
	for(int i=2;i<=5;i++){
		for(int j=1;j<=n;j++){
			a[i][j]=a[i-1][j]*a[1][j];
		}
	}
	for(int i=1;i<=5;i++){
		for(int j=1;j<=n;j++){
			prefix[i][j]=prefix[i][j-1]+a[i][j];
		}
	}
	while(m--){
		int l,r,k;cin>>l>>r>>k;
		cout<<(prefix[k][r]-prefix[k][l-1])%P<<"\n";
	}
	return 0;
} 

4.3、小郑的蓝桥平衡串

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const int N = 1001;
char s[N];
int prefix[N];
int main(){
	IOS;
	cin>>s+1;
	int n=strlen(s+1);
	for(int i=1;i<=n;i++){
		prefix[i]=prefix[i-1]+(s[i]=='L'?1:-1);
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=i;j<=n;j++){
			if((prefix[j]-prefix[i-1])==0){
				ans=max(ans,j-i+1);
			}
		}
	}
	cout<<ans<<"\n";
	return 0;
}	

4.4、大石头的搬运工

#include
using namespace std;
using Pair=pair<int,int>;
using ll=long long;
//带权中位数的计算
//|x-1| + |x-3| + |x-6| + |x-13|
//求,此时x=? 结果最小,毫无疑问的是等于中位数的时候
int main() {
	int n;cin >> n;
	vector<Pair> a(n);
	ll sw = 0;
	//p初始位置,w权值
	for(auto &[p,w]:a){
		cin>>w>>p,sw+=w;//计算w的和
	}
	sort(a.begin(), a.end());//根据pair的第一个大小排序,也就是p
	ll nw=0;//左侧的w数据
	int x=0;//中位数
	for (const auto &[p, w]: a) {
		//nw*2
		//因为找到最小的带权中位数
		if(nw*2<sw&&sw<=2*(nw+w)){
			x=p;break;
		}
		nw+=w;
	}
	//10^5*10^5 > 10^8 所以使用long long
	ll ans = 0;
	for (const auto &[p, w]: a) {
		ans+=(ll)w*abs(p-x);
	}
	cout <<ans<<'\n';
    return 0;
}

4.5、最大数组和

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
using ll = long long;
int main(){
	IOS;
	int t;cin>>t;
	while(t--){
		int n,k;cin>>n>>k;
		vector<ll> prefix(n+1,0),a(n,0);
		for(auto &v:a)cin>>v;
		sort(a.begin(),a.end());	
		for(int i=1;i<=n;i++){
			prefix[i]=prefix[i-1]+a[i-1];
		}	
		ll ans=0;
		for(int i=0;i<=k;i++){
			// 0 1 2 3 ... n-k-1
			// 2*k ... n-1
			ans=max(ans,prefix[n-(k-i)]-prefix[2*i]);
		}
		cout<<ans<<"\n";
	}
	return 0;
}	

4.6、四元组问题**

#include
using namespace std;
int main(){
	int n;cin>>n;
	if(n<4){
		cout<<"No"<<"\n";return 0;
	}
	int k=INT_MIN,m=INT_MAX;
	vector<int> v(n+1),rmin(n+1,m);
	for(int i=1;i<=n;i++)cin>>v[i];
	// a nums[d]
	//先找 c nums[d]
	for(int i=n-1;i>=1;i--){
		// i 位置右边最小的值是 rmin[i] 即为nums[d]
		rmin[i]=min(rmin[i+1],v[i+1]);
	}
	stack<int> s;
	for(int i=1;i<=n;i++){
		//k nums[b],v[i] nums[a],rmin[i] nums[d]
		//因为有rmin[i]的存在,所以就肯定有nums[c]
		if(v[i]<k&&v[i]>rmin[i]){//当前的值 
			cout<<"YES";return 0;
		}
		//单调栈
		//寻找 nums[a]
		while(!s.empty()&&s.top()<v[i]){
			k=max(k,s.top());
			s.pop();
		}	
		s.push(v[i]);
	} 
	cout<<"NO";
	return 0;
}

5、差分

5.1、区间更新(一维差分)

#include
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
/*
对差分数组做前缀和,可以得到原数组
for(int i=1;i<=n;i++)
	diff[i]=a[i]-a[i-1];
将区间都加上x:
	diff[l]+=x;
	diff[r+1]-=x;
*/
const int N = 1e5+5;
int a[N],diff[N];
int main() {
	IOS;
	int n,m;
	while(cin>>n>>m){
		for(int i=1;i<=n;i++){
			cin>>a[i];
			diff[i]=a[i]-a[i-1];
		}
		while(m--){
			int x,y,z;cin>>x>>y>>z;
			diff[x]+=z;
			diff[y+1]-=z;
		}
		for(int i=1;i<=n;i++)a[i]=a[i-1]+diff[i];
		for(int i=1;i<=n;i++)cout<<a[i]<<" ";
		cout<<"\n";
	}
	return 0;
}

5.2、肖恩的投球游戏加强版

#include
using namespace std;
const int N = 2001;
long long a[N][N],d[N][N];
void solve(const int &Case) {
	int n,m,q;cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			d[i][j]=a[i][j]-a[i][j-1]-a[i-1][j]+a[i-1][j-1];//差分
		}
	int x1,y1,x2,y2,c;
	while(q--){
		cin>>x1>>y1>>x2>>y2>>c;
		//操作区间数据
		d[x1][y1]+=c;
		d[x2+1][y1]-=c;
		d[x1][y2+1]-=c;
		d[x2+1][y2+1]+=c;
	}
	//前缀和求原数组
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+d[i][j];
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cout<<a[i][j]<<" \n"[j==m];
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

5.4、泡澡

#include
using namespace std;
const int N = 2e5+5;
using ll = long long;
ll a[N];		
void solve(const int &Case) {
	int n,w;cin>>n>>w;
	while(n--){
		int l,r,p;cin>>l>>r>>p;
		a[l]+=p;
		a[r]-=p;
	}
	for(int i=1;i<N;i++)a[i]=a[i]+a[i-1];
	for(int i=0;i<N;i++){
		if(a[i]>w){
			cout<<"No\n";return;
		}
	}
	cout<<"Yes\n";
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

6、离散化

6.1、离散化举例

#include
using namespace std;
vector<int> L;//离散化数组
int getidx(int x) {
	return lower_bound(L.begin(),L.end(),x)-L.begin();
}
const int N = 1e5 + 9;
int a[N];
int main() {
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	//将元素存入到L数组中去
	for(int i=1;i<=n;i++)L.push_back(a[i]);
	//排序去重
	/*unique的功能是去除相邻的重复元素(只保留一个),其实它并不真正把重复的元素删除,
	是把重复的元素移到后面去了,然后依然保存到了原数组中,
	然后 返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素*/
	sort(L.begin(),L.end());
	L.erase(unique(L.begin(),L.end()),L.end());
	cout<<"离散化数组为:";
	for(const auto &i:L)cout<<i<<" ";
	int v;cin>>v;
	cout<<getidx(v)<<"\n";
	return 0;
}

7、贪心

7.1、谈判(优先队列)

#include
using namespace std;
using ll =long long;
priority_queue<ll,vector<ll>,greater<ll>> pq;
void solve(const int &Case) {
	int n;cin>>n;
	for(int i=0;i<n;i++){
		int t;cin>>t;
		pq.push(t);
	}
	ll ans=0;
	while(pq.size()>1){
		ll x=pq.top();pq.pop();
		ll y=pq.top();pq.pop();
		ans+=x+y;
		pq.push(x+y);
	}
	cout<<ans<<"\n";
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.2、纪念品分组(双指针)

#include
using namespace std;
const int N = 300001;
int a[N];
void solve(const int &Case) {
	int w,n;cin>>w>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	sort(a,a+n);
	int l=0,r=n-1;
	int ans=0;
	while(l<=r){
		ans++;
		if(l==r)break;
		if(a[l]+a[r]<=w){
			l++;r--;
		}else{
			r--;
		}
	}
	cout<<ans<<"\n";
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.3、分糖果

#include
using namespace std;
const int N = 1e6+9;
char s[N];
//题意:将字符串分为x个,这个x个的大小差距要求尽可能小,让后找到里面最大的字符串
void solve(const int &Case) {
	int n,x;cin>>n>>x;
	cin>>s+1;
	sort(s+1,s+1+n);
	if(s[1]==s[n]){ // a a a a a a a  3
		for(int i=1;i<=n/x+(n%x?1:0);i++)cout<<s[i];
	}else if(s[1]==s[x]){ // a a a b b c d d  3
		for(int i=x;i<=n;i++)cout<<s[i];
	}else{// a a b c c d  3
		cout<<s[x];
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.4、珠宝的最大交替和

#include
using namespace std;
using ll = long long;
const int N = 1e6+5;
ll a[N];
void solve(const int &Case) {
	int n;cin>>n;
	for(int i=0;i<n;i++){
		int num;cin>>num;
		a[i]=abs(num);
	}
	ll sum=0;
	for(int i=0;i<n;i++){
		sum+=(ll)pow(-1,i)*a[i];
	}
	ll mx=INT_MIN,mn=INT_MAX;
	for(int i=0;i<n;i+=2){
		if(a[i]<mn)mn=a[i];
	}
	for(int i=1;i<n;i+=2){
		if(a[i]>mx)mx=a[i];
	}
	cout<<max(sum,sum+2*(mx-mn))<<"\n";
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.5、小蓝的礼物

#include
using namespace std;
using ll = long long;
const int N = 1e6+5;
ll a[N];
void solve(const int &Case) {
	int n,k;cin>>n>>k;
	for(int i=0;i<n;i++)cin>>a[i];
	sort(a,a+n);
	ll sum=0;
	for(int i=0;i<n;i++){
		if(sum+(a[i]+1)/2>k){
			cout<<i<<"\n";
			return;
		}
		sum+=a[i];
	}
	cout<<n<<"\n";
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.6、四个瓷瓶的神秘游戏**

#include
using namespace std;
using ll = long long;
ll num = 3;
ll func(const ll &a,const ll &b,const ll &c){
	ll A=a+2*b;
	ll B=0;
	ll C=c-b;
	ll t=C/3;
	if(A==0)return 0;
	C%=num;
	if(C==0||C==1){
		return A+3*t;
	}else return A+3*t+1;
}
int main(){	
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	vector<ll> a(4);
	for(auto &x:a)cin>>x;
	sort(a.begin(),a.end());
	cout<<max({func(a[0],a[1],a[2]),func(a[1],a[0],a[2]),func(a[2],a[0],a[1]),func(a[3],a[0],a[1])})<<"\n";
	return 0;
}

7.7、鸡哥的购物挑战

#include
using namespace std;
const int N =2e5+1;
long long a[N];
void solve(const int &Case){
	int n;cin>>n;
	for(int i=0;i<n;i++)cin>>a[i];
	//加一个 greater()那么就按照从大到小排序了
	sort(a,a+n,greater<int>());
	long long ans=0;
	for(int i=0;i<n;i+=2){//注意·
		if(i==n-1)continue;
		if(a[i]+a[i+1]>0)ans+=a[i]+a[i+1];
		else break;
	}
	cout<<ans<<"\n";
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T=1;
	for(int Case=1;Case<=T;Case++)solve(Case);
	return 0;
}

7.8、冒险者公会

#include
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
using namespace std;
using ll = long long;
int main(){	
	IOS;
	int m,n;cin>>m>>n;//m个冒险者,n个村庄
	vector<int> a(m);//每位冒险者的能力值
	for(auto &x:a)cin>>x;
	vector<vector<int>> b(n);//每个村庄的任务量
	int mxk=0;
	for(auto &x:b){
		int k;cin>>k;//第n个村庄的任务量  b[][]
		x.resize(k);//调整第n个村庄数量  
		for(auto &j:x)cin>>j;
		sort(x.begin(),x.end());//对第二维的向量排序
		mxk=max(mxk,k);//mxk是所有村庄中最大的任务量
	}
	sort(a.begin(), a.end());//能力值
	int j=n-1;
	
	//记录冒险者完成的任务数量
	vector<int> c(m);
	//初始化最大任务量为 0
	ll ans=0;
	
	for (int T = 0; T < mxk; T++) {
		int mx = 0;//m个冒险者,n个村庄
		for (int i = 0; i < n; i++) {
			// 取 vector 元素前一定要判断是否为空
			//遍历所有村庄,找到一个最大的难度值
			if (!b[i].empty())mx=max(mx, b[i].back());
		}
		//寻找能够完成当前任务的冒险者(能力值>=难度值)
		while (j > 0 && a[j - 1] >= mx)j--;
		if (a[j] < mx) { // 如果最难的任务不能被任何冒险者完成,则输出 -1
			cout << "-1\n";return 0;
		}
		for (int i = 0; i < n; i++) {
			if (!b[i].empty())b[i].pop_back();
		}
		c[j]++;//记录冒险者完成的任务数量
	}
	
	for (int i = 0; i < m; i++) {
		if (c[i] > 1) {
			if (i == m - 1) { // 当前没有比这个冒险者还强的了,但是仍然需要,所以输出 -1
				cout << "-1\n";return 0;
			}
			//一个人只能出战一次
			c[i + 1] += c[i] - 1, c[i] = 1;
		}
		if (c[i] == 1)ans += a[i];
	}
	cout<<ans<<'\n';
	return 0;
}

7.9、明日方舟大作战

#include
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
using namespace std;
using ll = long long;
using Pair = pair<int,int>;
int main(){	
	IOS;
	int n,m,B;cin>>n>>m>>B;
	vector<Pair> a(n);
	for(auto &[x,y]:a)cin>>x>>y;//攻击力,费用
	int mx = 0;
	for (int i = 0; i < m; i++) {
		int x;cin >> x;
		mx = max(mx, x);//敌人最大的生命值 mx
	}
	vector<int> f(B + 1, INT_MIN);
	f[0] = 0; 
	for (auto &[x, y]: a) {
		//如果当前物品的费用大于背包容量 B,则跳过此物品
		if (y > B)continue;
		//将当前状态向量 f 复制给 g,作为备份
		auto g = f;
		//swap(f) 将新创建的向量与向量 f 进行交换
		//这样做的目的是清空 f 中的内容,并将其大小调整为 B + 1
		//这种做法可以更有效地清空 f,
		//避免了遍历 f 来赋予初始值的过程,提高了效率
		vector<int>(B + 1, INT_MIN).swap(f);
		for (int i = 0; i < y; i++) {
			f[i] = g[i];
		}
		//更新背包容量大于等于当前物品费用的状态值
		for (int i = y; i <= B; i++) {
			f[i] = max(g[i], g[i - y] + x);
		}
	}
	int Mx = *max_element(f.begin(), f.end());
	if (Mx == 0)cout << "-1\n";
	else cout << (mx + Mx - 1) / Mx << '\n';
	return 0;
}

你可能感兴趣的:(C/C++,算法,蓝桥杯,c++)