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

被折叠的 条评论
为什么被折叠?



