ACM k进制高精度优化 URAL 1803 The Czechs' Rifles 滚动数组

这篇博客介绍了如何在ACM竞赛中针对k进制高精度计算进行优化,特别是当k较小(2<=k<=10)时。文章重点讲解了一种特殊的压位方法,将其转化为k^m进制,以此提高计算速度,并应用滚动数组进一步提升效率。文中通过具体的题目实例——URAL 1803 The Czechs' Rifles,展示了这种优化技术的实现和效果。

ACM k进制高精度优化 ,2<=k<=10(K比较小)

高精度模板

压位(与普通压位不同),即变为k^m进制,大大加大速度

(使用了滚动数组)

int x = 0,y = 1,z = 2;
x = (x+1) % 3;
y = (y+1) % 3;
z = (z+1) % 3;

D - The Czechs' Rifles
Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

The Czechoslovak Legion decided to stop the fierce fighting in Siberia and return home. However, it was not so easy to leave Russia, because they had too little money to pay for the sea voyage from Vladivostok to Europe. The Czechs decided to get the necessary amount of money by selling their rifles to the advancing Red troops. The total number of rifles they could sell was  n. The first two rifles were ordinary, so the Czechs asked only one rouble for each of them. The  ith rifle (  i ≥ 3) costs as much as the (  i−1)th and (  i−2)th rifles together.
The bank notes that circulated in Russia at that time had nominal values equal to powers of an integer  k (there were one-rouble,  k-rouble, k 2-rouble notes and so on). The Red troops had occupied enough printing plants for printing the necessary amount of notes. They paid for each rifle the exact amount of money the Czechs asked using the minimal possible quantity of notes.
When the Red Army got hold of the rifles, Chapaev asked Anka to order them according to the quantity of notes paid for each rifle. If the same quantity of notes was paid for two rifles, then the rifle with the smallest number should go first. Help Anka fulfill this request.

Input

The only line contains the integers  k and  n separated with a space (2 ≤  k ≤ 10; 3 ≤  n ≤ 50000).

Output

Output the permutation of the integers from 1 to  n corresponding to the numbers of rifles in the required order.

Sample Input

input output
10 8
1 2 3 4 8 7 5 6

Hint

After Anka fulfills Chapaev's request, the costs of the rifles in roubles will be {1, 1, 2, 3, 21, 13, 5, 8}.

暴力:

超时

/*
 * Author: NICK WONG
 * Created Time:  8/9/2014 15:17:54
 * File Name: d.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=50100;
const long long maxint=-1u>>1;
const long long maxlong=maxint*maxint;
typedef long long lint;
struct wjj
{
    int x,p;
};
wjj a[maxn];
int f[55][maxn],n,k;

void init()
{
    cin>>k>>n;
}

bool cmp(wjj a, wjj b)
{
    if (a.x<b.x) return true; else
        if (a.x==b.x && a.p<b.p) return true; else
            return false;
}

void work()
{
    memset(a,0,sizeof(a));
    memset(f[0],0,sizeof(f[0]));
    memset(f[1],0,sizeof(f[1]));
    f[0][++f[0][0]]=1; f[1][++f[1][0]]=1;
    for (int i=1; i<=n; i++) a[i].p=i;
    int x = 0;
    int y = 1;
    int z = 2;
    for (int i=3; i<=n; i++)
    {
        int len=max(f[x][0],f[y][0]),carry=0;
        f[z][0]=len;
        for (int j=1; j<=len; j++)
        {
            f[z][j]=f[x][j]+f[y][j]+carry;         
            if (f[z][j]>=k)
            {
                f[z][j]-=k;
                carry=1;
            } else
            {
                carry=0;
            }
            if (f[z][j]>=k)
            {
            	//cout<<i<<" "<<j<<endl;
            	//out(len);
            	//out(f[x][j]); out(f[y][j]);
            	//return;
            }
            a[i].x+=f[z][j];
        }
        if (carry>0)
        {
            f[z][++f[z][0]]=1;
            a[i].x+=1;
        }
        x = (x+1) % 3;
        y = (y+1) % 3;
        z = (z+1) % 3;
    }
    sort(a+1,a+1+n,cmp);
    //out(f[y][0]); return;
    //for (int i=1; i<=n; i++)
    //{ out(a[i].p); out(a[i].x); }
    for (int i=1; i<=n; i++)
        if (i==n) printf("%d\n",a[i].p); else printf("%d ",a[i].p);
}

int main()
{
    init();
    work();
    return 0;
}


正解:

Memory: 5069 KB Time: 656 MS
Language: G++ 4.7.2 Result: Accepted
/*
 * Author: NICK WONG
 * Created Time:  8/9/2014 15:17:54
 * File Name: d.cpp
 */
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=50100;
const long long maxint=-1u>>1;
const long long maxlong=maxint*maxint;
typedef long long lint;
struct wjj
{
    int x,p;
};
wjj a[maxn];
int f[55][maxn],n,k;
int g[10001000];

void init()
{
    cin>>k>>n;
}

bool cmp(wjj a, wjj b)
{
    if (a.x<b.x) return true; else
        if (a.x==b.x && a.p<b.p) return true; else
            return false;
}

void work()
{
	int kk = 1;
	for (int i =1 ; kk*k<=1000000; i ++) kk *= k;
	for (int i = 0 ; i <= kk-1;i ++)
	{
		int x = i;
		int tot =0;
		while (x!=0)
		{
			tot += x%k;
			x/=k;
		}
		g[i] = tot;
	}
	
    memset(a,0,sizeof(a));
    memset(f[0],0,sizeof(f[0]));
    memset(f[1],0,sizeof(f[1]));
    f[0][++f[0][0]]=1; f[1][++f[1][0]]=1;
    for (int i=1; i<=n; i++) a[i].p=i;
    int x = 0,y = 1,z = 2;
    for (int i=3; i<=n; i++)
    {
        int len=max(f[x][0],f[y][0]),carry=0;
        f[z][0]=len;
        for (int j=1; j<=len; j++)
        {
            f[z][j]=f[x][j]+f[y][j]+carry;  
            if (f[z][j]>=kk)
            {
                f[z][j]-=kk;
                carry=1;
            } else
            {
                carry=0;
            }
            a[i].x+=g[f[z][j]];
        }
        if (carry>0)
        {
            f[z][++f[z][0]]=1;
            a[i].x+=1;
        }
        x = (x+1) % 3;
        y = (y+1) % 3;
        z = (z+1) % 3;
    }
    sort(a+1,a+1+n,cmp);
    for (int i=1; i<=n; i++)
        if (i==n) printf("%d\n",a[i].p); else printf("%d ",a[i].p);
}


int main()
{
    init();
    work();
    return 0;
}



内容概要:本文详细阐述了工业母机技术领域中“高级结构设计工程师”这一岗位的全方位任职要求与职业发展路径,涵盖职位对标、目标企业、学历与证书要求、年龄范围、管理半径、晋升关键点、必备工作经验年限以及薪资待遇区间。重点突出该岗位对高端数控机床核心结构(如床身、主轴箱、导轨等)设计能力的要求,强调有限元分析、精度控制、热变形补偿、振动抑制等核心技术能力,并明确指出需具备项目主导经验、团队管理能力和跨部门协作经验。同时,根据不同企业类型和发展阶段,给出了清晰的年薪划分标准,体现了市场对该岗位的技术深度与综合能力的高度认可。; 适合人群:具备5年以上工业母机或高端机床结构设计经验,致力于向高级工程师、技术专家或管理岗位发展的结构设计从业者;或希望转型进入高端装备制造业的精密机械研发人员。; 使用场景及目标:①用于求职者精准定位职业发展方向,评估自身与高级岗位之间的能力差距;②辅助企业制定人才招聘标准与薪酬体系;③指导技术人员规划技能提升路径,聚焦核心技术积累与项目经验沉淀。; 阅读建议:建议结合个人职业发展阶段对照文中各项指标进行自我诊断,重点关注“晋升关键点”与“必备年限”部分,有针对性地补齐技术短板、积累主导项目经验,并注重专利成果与团队管理能力的培养,以全面提升竞争力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值