现在的位置: 首页 > 综合 > 正文

SGU 108 Self-numbers II(筛法+枚举)

2013年04月12日 ⁄ 综合 ⁄ 共 921字 ⁄ 字号 评论关闭

不用滚动数组会超空间,处理了之后又要用各种技巧优化防止超时间。

每个数字k各位上的加和psum与前一个数k-1的加和是有一定关系的:

k%10!=0,则psum++;

k如果是10的倍数,psum-=8

k如果是100的倍数,psum-=17

………………

 

//SGU 108 Self-numbers II 
//筛法+枚举
//by night_watcher

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

#define N 5000

struct NODE{
    int ul;
    int id;
    int num;
} node[N];

int n,m,psum;
bool a[64];

bool cmp1(const NODE x,const NODE y){
    return x.id<y.id;
}

bool cmp2(const NODE x,const NODE y){
    return x.ul<y.ul;
}

void cnt(int k){
    if(k%10){
        psum+=1;
        return ;
    }
    k/=10;
    psum-=8;
    while(k%10==0){
        psum-=9;
        k/=10;
    }
    return ;
}


int main(){
    int i,j,nid,selfcnt;
    while(cin>>n>>m){
        memset(a,1,sizeof(a));
        for(i=0;i<m;i++){
            cin>>node[i].id;
            node[i].ul=i;
        }
        sort(node,node+m,cmp1);
        selfcnt=0;
        psum=0;
        nid=0;
        for(i=1,j=0;i<=n;i++,j=(j+1)%64){
            if(a[j]){
                selfcnt++;
                while(selfcnt==node[nid].id){
                    node[nid++].num=i;
                }
            }
            cnt(i);
            a[(j+psum)%64]=0;
            a[j]=1;
        }
        sort(node,node+m,cmp2);
        cout<<selfcnt<<endl;
        cout<<node[0].num;
        for(i=1;i<m;i++){
            cout<<" "<<node[i].num;
        }
        cout<<endl;
    }
    return 0;
}

 

抱歉!评论已关闭.