关于521
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
2
-
描述
-
Acm队的流年对数学的研究不是很透彻,但是固执的他还是想一头扎进去。
浏览网页的流年忽然看到了网上有人用玫瑰花瓣拼成了521三个数字,顿时觉得好浪漫,因为每个男生都会不经意的成为浪漫的制造者。此后,流年走到哪里都能看到5、2、1三个数字,他怒了,现在他想知道在连续的数中有多少数全部包含了这三个数字。例如12356就算一个,而5111就不算。特别的,如果他看到了521三个数连续出现,会特别的愤怒。例如35210。
-
输入
-
多组测试数据:
一行给定两个数a,b(0<a,b<1000000),表示数字的开始和结束。
输出
- 一行显示他想要知道的数有几个及显示有多少个数字令他特别的愤怒。用空格隔开。 样例输入
-
200 500 300 900 1 600
样例输出
-
Case 1:2 0 Case 2:2 1 Case 3:6 1
3种方法
1.普通方法
01.
#include<iostream>
02.
using
namespace
std;
03.
#define MAX 1000000
04.
int
main()
05.
{
06.
int
a,b;
07.
int
s[6],d1[MAX],d2[MAX];
08.
for
(
int
i=125;i<1000000;i++)
09.
{
10.
int
n5=0,n2=0,n1=0;
11.
s[0]=i%10;
12.
s[1]=i/10%10;
13.
s[2]=i/100%10;
14.
s[3]=i/1000%10;
15.
s[4]=i/10000%10;
16.
s[5]=i/100000%10;
17.
int
t;
18.
for
(
int
j=0;j<4;j++)
19.
{
20.
if
(s[j]==1&&s[j+1]==2&&s[j+2]==5)
21.
{
22.
d2[i]=d2[i-1]+1;
23.
break
;
24.
}
25.
if
(j==3)
26.
d2[i]=d2[i-1];
27.
}
28.
for
(
int
j=0;j<6;j++)
29.
{
30.
if
(s[j]==5)
31.
n5++;
32.
else
if
(s[j]==2)
33.
n2++;
34.
else
if
(s[j]==1)
35.
n1++;
36.
if
(n1&&n2&&n5)
37.
d1[i]=d1[i-1]+1;
38.
else
39.
d1[i]=d1[i-1];
40.
}
41.
}
42.
int
count=0;
43.
while
(cin>>a>>b)
44.
{
45.
count++;
46.
if
(a<2)
47.
a=2;
48.
cout<<
"Case "
<<count<<
":"
<<d1[b]-d1[a-1]<<
" "
<<d2[b]-d2[a-1]<<endl;
49.
}
50.
return
0;
51.
}
2.动态规划
01.
#include<stdio.h>
02.
int
a[2][1000001]={0};
03.
int
main()
04.
{
05.
int
k=0,i,sum=0;
06.
for
(i=1;i<=1000000;i++)
07.
{
08.
if
((i%10==5||(i/10)%10==5||(i/100)%10==5||(i/1000)%10==5||(i/10000)%10==5||(i/100000)%10==5)&&(i%10==2||(i/10)%10==2||(i/100)%10==2||(i/1000)%10==2||(i/10000)%10==2||(i/100000)%10==2)&&(i%10==1||(i/10)%10==1||(i/100)%10==1||(i/1000)%10==1||(i/10000)%10==1||(i/100000)%10==1))
09.
{
10.
sum++;
11.
if
(i/1000==521||(i/100)%1000==521||(i/10)%1000==521||i%1000==521)
12.
k++;
13.
}
14.
a[0][i]+=sum;
15.
a[1][i]+=k;
16.
}
17.
int
m,n,w=0;
18.
while
(
scanf
(
"%d%d"
,&n,&m)!=EOF)
19.
printf
(
"Case %d:%d %d\n"
,++w,a[0][m]-a[0][n-1],a[1][m]-a[1][n-1]);
20.
}
3.c++库函数
01.
#include<iostream>
02.
#include <string>
03.
#include <sstream>
04.
#include <cstdio>
05.
#include <cstdlib>
06.
using
namespace
std;
07.
//用打表法解决,本题将整数转换成字符串,然后查找字符串判断是否有5,2,1,521
08.
//题目感觉略坑,直接用stringstrean去将整数转换成字符串超时,但用sprintf可以通过
09.
int
table[1000000]={0},table521[1000000]={0};
10.
11.
void
make_table()
12.
{
13.
for
(
int
i = 125; i < 1000000; ++ i)
14.
{
15.
table[i]=table[i-1];
16.
table521[i] = table521[i-1];
17.
char
c[10];
18.
sprintf
(c,
"%d"
,i);
19.
/*
20.
stringstream ss;
21.
ss << i;
22.
string num(ss.str());*/
23.
string num(c);
24.
if
(num.find(
'5'
)!= string::npos && num.find(
'2'
)!=string::npos && num.find(
'1'
)!=string::npos){
25.
table[i]++;
26.
if
(num.find(
"521"
)!=string::npos) table521[i]++;
27.
}
28.
}
29.
}
30.
31.
int
main()
32.
{
33.
make_table();
34.
int
a,b,cnt = 0;
35.
while
(cin >> a >> b){
36.
printf
(
"Case %d:%d %d\n"
,++cnt,table[b]-table[a-1],table521[b] - table521[a-1]);
37.
}
38.
}
-
多组测试数据: