您的位置:首页 > 其它

BIT2014级软件学院程序设计-10 ⑨的统计

2016-03-02 15:35 225 查看
众所周知,琪露诺(チルノ,Cirno)是幻想郷 (げんそうきょう)中首屈一指的天才,可以说⑨就是她的代名词。
然而如今,她遇到了一个和⑨有关的难题。你能帮助她么?
题目是这样的,给出两个数 a 和 b (0 <= a <= b <= 10^10000),求 a 到 b 之间(包括a和b)的数字中,有多少个数字是包含9的(例如 19,910 等都是包含9的数字)。

输入

第一行为一个数字 T (0 < T <= 100) 表示数据组数。
之后的 T 行,每行包含两个数 a 和 b (0 <= a <= b <= 10^10000)。

输出

对每组数据输入,输出一个数字,表示 a到 b 之间的数字中(包括a和b),有多少个数字是包含9的。(注意:答案可能很大)

Sample Input

2
0 9
0 100

Sample Output

1
19
感觉基本应该是程设最难的一道题了把,我感觉是。
先转化成求0-a和0-b有多个数字9
数量很大要用到高精度。用数组来存数字。
然后比如13012958就是求10000000的9+3000000的9+10000的9+2000的9+958
至于10000000有多少个9就可以直接用公式了。
10:1;100:1*9+10=19;1000:19*9+100;...........................................
然后计算高精度注意一些东西就好了,比如压缩一下位数,还有应用一下秦九韶公式就好

#include<stdio.h>
#include<string.h>
#define	mod 100000000
#define maxn 10080
#define end 1300
char a[maxn];
char b[maxn];
int num[maxn];
int ans[3][end+2];//答案数组

void big_sum(int *a1, int ak)
{
int i, k=0;
a1[end] += ak;
for(i=end;i>=0;i--)
{
if(a1[i]>=mod)
{
a1[i]-=mod;
a1[i-1]++;
}
else break;
//if(a1[end]>mod)
//a1[end]-=mod;
//a1[end-1]++;//为了节省时间复杂度没有用循环,不够严谨,可能全是999999999需要进位
}
return;
}

void big_cheng(int *a1,int ak)
{

int i, k;
int j=0;
while(!a1[j])
j++;//j是第一位非0
for (i = end;i>=j;i--)
a1[i] *= ak;
//a1[0] *= ak;
k = 0;
for (i = end;i>=j-2;i--)//进位
{
a1[i] += k;
k = a1[i] / mod;
a1[i] = a1[i] % mod;
}
return;
}
void big_jian(int *a1, int *a2, int *a3)
{
int i;
for (i = end;i >= 0;i--)
{
a1[i] = a2[i] - a3[i];
}
for (i = end;i >0 ;i--)
{
if (a1[i] < 0)
{
a1[i -1]-=1;
a1[i] += mod;
}
}
return;
}

void search_9(int length,int flag)//flag为0 是第一个数,1是第二个数
{//利用秦九韶算法
int i;
int flag9=0;
int ans1[end+5]={0};
int ans2[end+5]={0};
ans1[end]=num[0];

ans2[end]=num[0];
if(num[0]==9)//判断9
flag9=1;
for (i = 1;i < length;i++)
{

big_cheng( ans1,10);//高精度乘法
big_sum(ans1, num[i]);//高精度加法

if (flag9)
{
big_cheng(ans2, 9);
}
else {
big_cheng(ans2, 9);
big_sum(ans2, num[i]);
}
if(num[i]==9)
flag9=1;
}
big_jian(ans[flag],ans1, ans2);
return;
}
int main()
{
//freopen("F:in.txt","r",stdin);
//	freopen("F:out1.txt","w",stdout);

int T;
int la, lb;
int i, j,flag2;
scanf("%d", &T);
while(T--)
{
flag2 = 0;
//	memset(ans,0,sizeof(ans));
//	memset(num,0,sizeof(num));
scanf("%s%s", a, b);
la = strlen(a);lb = strlen(b);
for (i = 0;i < la;i++)
{
num[i] = a[i] - '0';

}search_9(la, 0);
//	memset(num,0,sizeof(num));
for (i = 0;i < lb;i++)
{
num[i] = b[i] - '0';
if (num[i] == 9)
flag2 = 1;
}

search_9(lb,1);
big_jian(ans[2], ans[1], ans[0]);
ans[2][end] = ans[2][end] + flag2;

for(i=end;i>=0;i--)
{
if(ans[2][i]>=mod)
ans[2][i-1]++;
else break;
}

for (i = 0;i <= end;i++)
{
if (ans[2][i])
break;
}
printf("%d", ans[2][i]);
i++;

while (i <= end)
{

printf("%08d", ans[2][i]);
i++;
}
printf("\n");
}
return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: