关于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
题目

 

这题我特别愚蠢的把输入视为字符串,代码变得臃肿又繁琐

超时原因:给每个数打表,最后把区间内数相加,要是有多组很大的数,比如1~999987,4~777777……复杂度就是指数级

修改:表中每个元素i存储0~i的总个数

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;

const int Max = 1000000;

int a[Max];
int b[Max];

int main()
{
              int x,y;
              memset(a,0,sizeof(a));
              memset(a,0,sizeof(b));
              for(int i = 125; i < 1000000; i++)
                {
                      int m = 0;
                      int n = 0;
                      char s[8];
                      int cnt = 0;
                      //itoa(i,s,10);
                      //cout << s;
                      int j = i;
                      while(j > 0)
                      {         //这个错误也常犯   
                              s[cnt] = j%10+'0';
                              j = j/10;
                               // cout << j << endl;
                              cnt ++;
                      }
                      int l = strlen(s);
                      if(strstr(s,"5")&&strstr(s,"2")&&strstr(s,"1"))
                        m++;
                      if(strstr(s,"125"))
                        n++;
                        a[i] = a[i-1] + m;  //记录0到i之间的521个数 
                        b[i] = b[i-1] + n;
                       // cout << b[i];     
                }
                int cn = 1;
                while(scanf("%d%d",&x,&y)==2)
                {
                        int p = a[y] - a[x-1],q = b[y] - b[x-1];
                          printf("Case %d:%d %d\n",cn,p,q);
                          cn++;
                }
              
    
    return 0;
}
我臭长的代码
 
#include<stdio.h>
int a[2][1000001]={0};
int main()
{
int k=0,i,sum=0;
for(i=1;i<=1000000;i++)
{
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))
{sum++;
if(i/1000==521||(i/100)%1000==521||(i/10)%1000==521||i%1000==521)k++;}
a[0][i]+=sum;
a[1][i]+=k;
}
int m,n,w=0;
while(scanf("%d%d",&n,&m)!=EOF)
printf("Case %d:%d %d\n",++w,a[0][m]-a[0][n-1],a[1][m]-a[1][n-1]);
}
        
很暴力的最优代码