【HDOJ 5373】The shortest problem
暴力 比赛时用字符串做 无限超时 后来更新各种姿势最后直接打表打出前120W个数的各位加和。。。 还是跑了很久
回来后想到用数组。。。不提了= =全是泪……
代码如下:
//字符串挫代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <list>
#include <vector>
#define INF 0x3f3f3f3f
#define esp 1e-8
#define ll long long
#define sz 2620000
using namespace std;
char str[2333333];
int num[sz][2];
int get(int n)
{
if(n < 10) return 10;
else if(n < 100) return 100;
else if(n < 1000) return 1000;
else if(n < 10000) return 10000;
else if(n < 100000) return 100000;
else if(n < 1000000) return 1000000;
else return 10000000;
}
int sm(int n)
{
int s = 0;
while(n)
{
s += n%10;
n /= 10;
}
return s;
}
int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
int t,i,a,z = 0,k,j,n;
ll sum,tmp;
memset(num,0,sizeof(num));
num[0][1] = 1;
for(i = 1; i <= sz; ++i)
{
if(num[i][0]) continue;
num[i][1] = get(i);
num[i][0] = sm(i);
for(j = i*10; j <= sz; j *= 10)
{
num[j][1] = get(j);
num[j][0] = num[i][0];
}
}
while(scanf("%d %d",&n,&t),t != -1 || n != -1)
{
if(n == 0)
{
printf("Case #%d: Yes\n",++z);
continue;
}
sprintf(str,"%d",n);
sum = 0;
a = 0;
for(i = 0; str[i]; ++i)
{
sum += str[i]-'0';
a = (a*10 + str[i]-'0')%11;
}
while(t)
{
a = (a*num[sum][1] + sum)%11;
if(t == 1) break;
sum += num[sum][0];
//for(j = k; j >= 10; j /= 10) sum += tmp%j/(j/10);
t--;
}
printf("Case #%d: %s\n",++z,a? "No": "Yes");
}
}
//数组模拟高效代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <list>
#include <vector>
#define INF 0x3f3f3f3f
#define esp 1e-8
#define ll long long
using namespace std;
int str[111111];
int tp;
int len(int x)
{
if(x < 10) return 10;
if(x < 100) return 100;
if(x < 1000) return 1000;
if(x < 10000) return 10000;
if(x < 100000) return 100000;
if(x < 1000000) return 1000000;
return 10000000;
}
int main()
{
int t,i,sum,tmp,a,z = 0;
while(~scanf("%d %d",&str[0],&t) && str[0] != -1 && t != -1)
{
if(str[0] == 0)
{
printf("Case #%d: Yes\n",++z);
continue;
}
sum = 0;
tp = 1;
while(t)
{
if(sum) tmp = sum;
else tmp = str[0];
while(tmp)
{
sum += tmp%10;
tmp /= 10;
}
str[tp++] = sum;
t--;
}
a = 0;
for(i = 0; i < tp; ++i)
{
a = (a*len(str[i]) + str[i])%11;
}
printf("Case #%d: %s\n",++z,a? "No": "Yes");
}
}
//更简洁的代码
#include <iostream>
#include <cstdio>
using namespace std;
int tot,k;
void get(int x)
{
int y = x,cnt = 1;
while(x)
{
tot += x%10;
x /= 10;
cnt *= 10;
}
k = (k*cnt+y)%11;
}
int main()
{
int n,t,z = 0;
while(~scanf("%d %d",&n,&t) && n != -1)
{
tot = k = 0;
get(n);
while(t--)
get(tot);
printf("Case #%d: %s\n",++z,k? "No": "Yes");
}
return 0;
}