NOIP 2006 提高组 复赛 digital 2k 进制数
来源:互联网 发布:pyqt5 tabwidget数据 编辑:程序博客网 时间:2024/05/16 05:50
NOIP 2006 提高组 复赛 digital 2k 进制数
//洛谷 P1066 2^k进制数//提示:作为结果的正整数可能很大,但不会超过200位,考虑用高精度算法,加
//没什么思路,翻看他人做法,积累经验,该题还考什么,排列组合,猜测。
//http://hzwer.com/794.html此文写得不错,同时,也应证了本人的想法。
//自个举了个例子3 8
//2位 C[7][2]=21
//3位 首位最大值(11)2 (3)10 C[6][2]+c[5][2]+c[4][2]=31
//首位放1 C[6][2] 2 c[5][2] 3 c[4][2]
//组合数公式,可以由杨辉三角而来,c[i][j]=c[i-1][j]+c[i-1][j-1];
//突然意识到,用高精度算法的程序,测试起来极其困难。但还是找到了测试办法,不打印测试数据,打印要计算的数据
//提交,全报MLE,没辙,将 int c[520][520][210];改成int c[520][520][100];
//c[0][0][0]=1,c[0][0][1]=0;//更改此句memset(c,0,sizeof(c));算法效率立马得到了极大的提高,由2637ms提高到45ms
//该题疑问,数组最大能开到多大,或者说内存大小如何计算。猜测10^7到10^8之间,待日后查证
//该题耗时4天,主要时间花在理解 除首位计数情况,包含首位计数情况。2017-5-17 AC
#include <stdio.h>
#include <string.h>
int c[520][520][100];//标准是512 512 200现在安排有一定弹性空间,隐忧,容易内存溢出
int ans[210];
void plus1(int x[],int y[],int z[]){//3 z[0]存储数据长度,z[1]是最低位,打印注意,要从最高位打起
int i;
z[0]=x[0]>y[0]?x[0]:y[0];
for(i=1;i<=z[0];i++){
z[i]+=x[i]+y[i];
z[i+1]=z[i]/10;//进位, 2 此处写成 z[i+1]=z[i]%10;
z[i]%=10;//2 此处写成 z[i]/=10;
}
if(z[z[0]+1]>0)
z[0]++;//当前数据长度
}
void plus2(int x[],int y[]){
int i;
x[0]=x[0]>y[0]?x[0]:y[0];
for(i=1;i<=x[0];i++){
x[i]+=y[i];
x[i+1]+=x[i]/10;//4 此处写成x[i+1]+=x[i]/10 进位,2 此处写成 x[i+1]=x[i]%10;
x[i]%=10;//2 此处写成 x[i]/=10;
}
if(x[x[0]+1]>0)
x[0]++;//当前数据长度
}
int main(){
int k,w,b,h,i,j;
scanf("%d%d",&k,&w);
b=1<<k;
h=1<<w%k;
c[0][0][0]=1,c[0][0][1]=0;//更改此句memset(c,0,sizeof(c));算法效率立马得到了极大的提高,由2637ms提高到45ms
memset(ans,0,sizeof(ans));
for(i=1;i<b;i++)//打表,排列组合
for(j=0;j<=i;j++)//1此处写成for(j=0;j<i;j++)
if(j==0||i==j){//此句写得很棒,配合上c[0][0][0]=1,c[0][0][1]=0;对于 c[i][j]=c[i-1][j]+c[i-1][j-1];计算,无懈可击.自认为关于组合数的计算,这个写法是相当棒的。
c[i][j][0]=1;//数据长度
c[i][j][1]=1;//初始数据为1
}else
plus1(c[i-1][j],c[i-1][j-1],c[i][j]);
for(i=2;i<=w/k&&i<b;i++)//除首位的情况 i<=w/k除首位情况,i<b若位数比较多,不能超越可选数字个数b-1
plus2(ans,c[b-1][i]);
for(i=1;i<h&&i+w/k<b;i++)//有首位的情况 i<h在首位里取1,2,...,h-1的情况,同时总需求个数i+w/k不能超越数字个数b-1
plus2(ans,c[b-1-i][w/k]);//4 此处写成 plus2(ans,c[b-1-i][i]);
for(i=ans[0];i>=1;i--)//3 z[0]存储数据长度,z[1]是最低位,打印注意,要从最高位打起 此处写成 for(i=1;i<=ans[0];i++)
printf("%d",ans[i]);
printf("\n");
return 0;
}
0 0
- NOIP 2006 提高组 复赛 digital 2k 进制数
- P1066 2^k进制数 NOIP 2006 提高组 第四题
- NOIP 提高组复赛 day1 国王游戏
- Noip 2014 提高组复赛 解题报告
- Noip 2014年 提高组复赛
- NOIP 2015 提高组复赛试题
- NOIP 提高组 复赛 怎么训练
- NOIP 1998 提高组 复赛 车站
- NOIP 1999 提高组 复赛 拦截导弹
- NOIP 1997 提高组 复赛 棋盘问题
- NOIP 2002 提高组 复赛 字串变换
- NOIP 2002 提高组 复赛 字串变换
- NOIP 2005 提高组 复赛 river 过河
- NOIP 2004 提高组 复赛 alpha 虫食算
- 2013 NOIP复赛 提高组 C++
- Codevs P1157 2k进制数 2006年NOIP全国联赛提高组
- (c语言)NOIp 2006 提高组 4 2^k进制数
- NOIP 2006 提高组 复赛 budget 金明的预算方案
- unicode Ascii gbk字符集和utf-8 utf-16编码
- 张量初步学习
- 同一tomcat下实现多应用session共享 单点登录
- Linux C语言编程-Linux网络通信--Linux上使用套接字(socket)来处理信息---编写一个单进程非阻塞多客户的套接字客户端
- Mysql数据库锁-表级锁分析
- NOIP 2006 提高组 复赛 digital 2k 进制数
- numpy的linalg模块
- 【Shell】-- 入门笔记(1) : 变量、字符串、数组、参数及基本运算符
- 继承
- Ubuntu server 安装CUDA 8.0
- 数组中只出现一次的数字(Java实现)
- CentOS下图形界面服务开启关闭以及不同运行级别的转换
- ssh框架关于ERROR Dispatcher:38
- 连续函数微分和离散函数的差分初解