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

hdu 4669 DP

2013年10月14日 ⁄ 综合 ⁄ 共 1295字 ⁄ 字号 评论关闭

不好写思路....比赛的时候有个地方想错了,搞得只会求不是圈的....最后看了http://www.cnblogs.com/kuangbin/archive/2013/08/13/3255856.html  的在圈那一部分的实现...哎...当时差一点就出来了............

AC代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

int number[50005];
int digits[50005];
int counts[2][202];
int N, K, now, pre;
__int64 ans;
int iend[50005];
int Ten[10];

int getdigits( int n ){
	if( n == 0 ){
		return 1;
	}
	int cnt = 0;
	while( n ){
		cnt++;
		n /= 10;
	}
	return cnt;
}

int main(){
	while( scanf( "%d%d", &N, &K ) != EOF ){
		memset( counts, 0, sizeof( counts ) ); 
		ans = 0;
		Ten[0] = 1;
		for( int i = 1; i < 5; i++ ){
			Ten[i] = Ten[i-1] * 10 % K;
		}

		for( int i = 0; i < N; i++ ){
			scanf( "%d", &number[i] );
			digits[i] = getdigits( number[i] );
		}

		now = 1;
		pre = 0;
		for( int i = 0; i < N; i++ ){
			now ^= 1;
			pre ^= 1;
			memset( counts[now], 0, sizeof( counts[now] ) );
			counts[now][number[i]%K]++;
			int s = pow( 10, digits[i] );
			for( int j = 0; j < K; j++ ){
				counts[now][(s*j+number[i])%K] += counts[pre][j];
			}
			ans += counts[now][0];
		}

		iend[N-1] = number[N-1] % K;
		int temp = digits[N-1];
		int s = Ten[temp];
		for( int i = N - 2; i >= 0; i-- ){
			iend[i] = number[i] * s % K + iend[i+1];
			iend[i] %= K;
			temp += digits[i];
			s = s * Ten[digits[i]] % K;
		}

		temp = digits[0];
		s = Ten[digits[0]];
		int tt = number[0] % K;
		for( int i = 0; i < N - 1; i++ ){
			counts[now][iend[i]]--;
			for( int j = 0; j < K; j++ ){
				int ppp = ( j * s % K + tt ) % K;
				if( ppp == 0 ){
					ans += counts[now][j];
				}
			}
			tt = tt * Ten[digits[i+1]] + number[i+1];
			tt %= K;
			temp += digits[i+1];
			s = s * Ten[digits[i+1]] % K;
		}
		printf( "%I64d\n", ans );
	}
	return 0;
}

 

抱歉!评论已关闭.