q1:2的幂数
时间限制: 1.000 Sec 内存限制: 128 MB
题目描述
小明开始学习二进制转化到十进制,其中要用到2的幂(2的3次幂就是3个2相乘),他觉得这个很有意思。既然通过2的幂相加可以得到十位数,那么反过来,一个十进制数是否可以通过若干个2的幂相加得到呢?
小明开始研究起来,他先列出了所有2的幂:1,2,4,8,16,32,64……。
4=1+1+1+1
4=1+1+2
4=2+2
4=4 4共有4种方法
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7= 1+1+1+2+2
7=1+1+1+4
7=1+2+2+2
7= 1+2+4
共有6种方法。1+2+4和2+1+4认为是同一个等式,因为它们的组成相同。
现在小明想要知道,给出一个十进制数,可以写出多少种,用若干个2的幂数相加的式子。
输入
第一行包含1个正整数n, 1<=n<=1000。
输出
共1行,n能用2的幂数相加的不同式子的种数。
样例输入 Copy
7
样例输出 Copy
6
思维题:
(1)特殊情况:n=1,只有一种
(2)n为奇数:f(n)=f(n-1),把n拆成1和n-1,1一定有,所以f(n)=f(n-1)
(3)n为偶数:f(n)=f(n-1)+f(n/2)
{
1.分出一个1:f(n-1)
2.分成的每个数都除以2,f(n/2)
}
ac代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int f(int n)
{
if(n==1)
return n;
else
{
if(n%2==1)
return f(n-1);
else
return f(n-1)+f(n/2);
}
}
int main()
{
cin>>n;
cout<<f(n);
return 0;
}
q2:平方数
时间限制: 1.000 Sec 内存限制: 128 MB
题目描述
珍珍学习乘法时,发现4=2*2,9=3*3,…,而2不可能分解为二个相同整数的乘积,但可以分解为1*1+1*1。她想知道对任意的正整数n,把它分解为几个整数与自身相乘之和,有多少种方案呢?
输入
输入只有一行,该行只有一个正整数n。
输出
输出只有一行,该行只有一个正整数,表示总方案数。
样例输入 Copy
13
样例输出 Copy
6
提示
30%的数据,1≤n≤10;
80%的数据,1≤n≤300;
100%的数据,1≤n≤800。
f[x][y]:y表示当前的值,
1.如果y=n时,说明该方式可以组成n,答案加1;
2.如果y>n||x>sqrt(n),说明该种方式无法组成n,答案加0;
3.如果a[x][y]不为0,说明该值在前面已经讨论过,例如,82=1*1+9*9,9在前面已经求了,直接带入就可以
4.如果123都不满足就处理该值,最后返回a[x][y]
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
int a[1000][1000];
int f(int x,int y)
{
if(y==n) return 1;
if(y>n||x>sqrt(n)) return 0;
if(a[x][y]) return a[x][y];
for(int i=x;i<=sqrt(n);i++)
{
a[x][y]+=f(i,y+i*i);
}
return a[x][y];
}
int main()
{
cin>>n;
cout<<f(1,0);
return 0;
}
q3:素数环
时间限制: 1.000 Sec 内存限制: 128 MB
提交 状态
题目描述
输入正整数n,把整数1,2,3,……,n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好输出一次。按字典序由小到大输出所有可能的排列。
输入
一行,正整数N(1<N <= 16)。
输出
若干行,每行一个符合要求的排列,两个整数之间用一个英文输入法下的空格隔开(半角空格)。如果无符合要求的排列,输出“no answer”,不包含引号,两单词之间有一个半角空格。
样例输入 Copy
6
样例输出 Copy
1 4 3 2 5 6 1 6 5 2 3 4
提示
素数:指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
字典序由小到大输出:在本题指的是多个排列由左及右比较,第一位小的排列先输出,若第一位相等,第二位小的排列先输出,依此类推。
代码超时,不会了,没法改了
思路:
首先根据数据范围求出该范围内的素数存入ss[ ];
将a[0]赋值为1
if(n==3||n==5||n==7||n==9||n==11||n==13||n==15),无法形成素数环,输出no answer
else 一个简单的dfs
1.边界:当s==n时,如果a[0]+a[[n-1]为素数,则输出该组合
2.未到边界,就枚举试各个值
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int st[20];
int a[20];
int ss[50];
void dfs(int s)
{
if(s==n&&ss[a[0]+a[n-1]])
{
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
{
for(int i=2;i<=n;i++)
{
if(!st[i]&&ss[i+a[s-1]])
{
st[i]=1;
a[s]=i;
dfs(s+1);
st[i]=0;
}
}
}
}
int f(int i)
{
int j;
for(j=2;j*j<=i;j++)
if(i%j==0) return 0;
return 1;
}
int main()
{
for(int i=3;i<=35;i++)
{
if(f(i))
ss[i]=1;
}
cin>>n;
a[0]=1;
if(n==3||n==5||n==7||n==9||n==11||n==13||n==15)
{
cout<<"no answer";
}
else
{
dfs(1);
}
return 0;
}