算法学习日记(十三)

凑平方数

把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721

再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等…

注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。

#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
#include<set>
#define  ll long long 
using namespace std;
int arr[10]={0,1,2,3,4,5,6,7,8,9};
ll nums[10];
int ans;
set <string> t;
bool is(ll k)
{
	double a=sqrt(k);
	if(a==(ll)a)
	{
		return true;
		
		
	}
	
	return false;
}
void dfs(int n,int x)
{

if(n==10)
{
	ll temp[10];
	copy(nums,nums+x,temp);
	sort(temp,temp+x);
	char str[1000]; 
	string k;
	for(int i=0;i<x;i++){
		 
          sprintf(str,"%lld",temp[i]);
          
           k+=str;
           k+=',';
        }
  
   
	t.insert(k);
	cout<<k<<endl;
	return;
}
if(arr[n]==0)
{
	nums[x]=0;
	dfs(n+1,x+1);
}
else
{
	ll k=0;
	for(int i=n;i<10;i++)
	{
	
	k=10*k+arr[i];
			if(is(k))
	{
		nums[x]=k;
		dfs(i+1,x+1);
	}
		
	}


	
	
	
}


}
int main()
{
do
{	
dfs(0,0);
}while(next_permutation(arr,arr+10));

cout<<t.size()<<endl;
return 0;
}


机器人塔

X星球的机器人表演拉拉队有两种服装,A和B。
他们这次表演的是搭机器人塔。

类似

A
B B
A B A
A A B B
B B B A B
A B A B B A

队内的组塔规则是:

A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。

你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。

输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。

要求输出一个整数,表示可以产生的花样种数。

例如:
用户输入:
1 2

程序应该输出:
3

再例如:
用户输入:
3 3

程序应该输出:
4

资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。


#include<iostream>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
using namespace std;
int m,n;
char temp[1000];
char temp1[1000];
int vis[1000];
int sum;
int k,ans;
int judge(int z)
{
	int sum_a=0,sum_b=0;
	
	strcpy(temp1+1,temp+1);

	while(z)
	{
		for(int i=1;i<=z;i++)
		{
				cout<<temp1[i];
		if(temp1[i]=='a')
		{
			sum_a++;
		}
		if(temp1[i]=='b'){
			sum_b++;
		}
		}cout<<endl;
	
		for(int i=1;i<=z-1;i++)
		{
			if(temp1[i]==temp1[i+1])
			{
				temp1[i]='a';
				
				
			}
			
			else
			{
				temp1[i]='b';
				
				
			}
			
		}
		z--;
	}
		cout<<"a "<<sum_a<<" b "<<sum_b<<endl; 
	if(sum_a==m&&sum_b==n)
	{
		return 1;
		
	}
	return 0;
	
	
	
}
void dfs(int cur)
{
if(cur==k+1)
{
	if(judge(k))
	{
		
		ans++;
	
		
	}
		return;
}
	





		temp[cur]='a';
		dfs(cur+1);
		temp[cur]='b';
		dfs(cur+1);
	


	




}
int main()
{
cin>>m>>n;
for(int i=1;i<50;i++)
{	sum+=i;
	if(sum==m+n)
	{
	k=i;
	} 
}
//找出底层所有可能 
//cout<<k<<endl;
dfs(1);
cout<<ans<<endl;

return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值