20201022 day42 模拟(十四)
1 自然数的拆分
problem
给定\(n\),将其拆分成至少2个至多\(n\)个自然数相加,以字典序从小到大输出。
solution
朴素dfs。
code
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
int n,a[110];
int read(){
int a=0,op=1;char c;c=getchar();
while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
return a*op;
}
void print(int len)
{
for (int i=1;i<len-1;i++)
printf("%d+",a[i]);
printf("%d",a[len-1]);
printf("\n");
}
void dfs(int pos,int left,int now)
{
if (left==0 && pos>2) print(pos);
if (now>left) return;
for (int i=now;i<=left;i++)
a[pos]=i,dfs(pos+1,left-i,i);
}
int main()
{
freopen("decompose.in","r",stdin);freopen("decompose.out","w",stdout);
n=read();
dfs(1,n,1);
return 0;
}
2 进制转换
problem
我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 \(10\) 为底数的幂之和的形式。
例如 \(123\) 可表示为 \(1 \times 10^2+2\times 10^1+3\times 10^0\) 这样的形式。
与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置为指数,以 \(2\) 为底数的幂之和的形式。 一般说来,任何一个正整数 \(R\) 或一个负整数 \(-R\) 都可以被选来作为一个数制系统的基数。如果是以 \(R\) 或 \(-R\) 为基数,则需要用到的数码为 \(0,1,....R-1\)。
例如当 \(R=7\) 时,所需用到的数码是 \(0,1,2,3,4,5,6\),这与其是 \(R\) 或 \(-R\) 无关。如果作为基数的数绝对值超过 \(10\),则为了表示这些数码,通常使用英文字母来表示那些大于 \(9\) 的数码。
例如对 \(16\) 进制数来说,用 \(A\) 表示 \(10\),用 \(B\) 表示 \(11\),用 \(C\) 表示 \(12\),以此类推。 在负进制数中是用 $-R $ 作为基数,例如 \(-15\)(十进制)相当于 \(110001\) (\(-2\)进制),并且它可以被表示为 \(2\) 的幂级数的和数: $$110001=1\times (-2)^5+1\times (-2)^4+0\times (-2)^3+0\times (-2)^2+0\times (-2)^1 +1\times (-2)^0$$ 设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数。
输入样例 #1
30000 -2
输出样例 #1
30000=11011010101110000(base-2)
输入样例 #2
-20000 -2
输出样例 #2
-20000=1111011000100000(base-2)
【数据范围】 对于 \(100\%\) 的数据,\(-20 \le R \le -2\),\(|n| \le 37336\)。
NOIp2000提高组第一题
solution
和正进制一样,每次取的余数保证在0m-1之间。(例如m=-16,则余数应该在015)就可以直接输出。
所以用系统的“%”运算符的时候必须注意检查是不是在该范围(可能在m+1~0),否则就调整。
调整的方法是:如果余数<0,那么:余数-=m;商++;
code
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int maxn=1e5+10;
int read(){
int a=0,op=1;char c;c=getchar();
while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
while(c>='0'&&c<='9'){a*=10,a+=c^48,c=getchar();}
return a*op;
}
int n,r;
char js[]="0123456789ABCDEFGHIJ";
stack<int>s;
int main()
{
freopen("t1.in","r",stdin);freopen("t1.out","w",stdout);
n=read(),r=read();
printf("%d=",n);
while(n){
int a=n%r;
n/=r;
if(a<0) {a-=r;n++;}//如果余数为负数,余数减去进制数,商加1
s.push(a);
}
while(!s.empty()){
printf("%c",js[s.top()]);
s.pop();
}
printf("(base%d)\n",r);
return 0;
}