HDU 2108 字符串递归

2 篇文章 0 订阅
2 篇文章 0 订阅
 Problem G Mod problem

Accept: 6    Submit: 29
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Given one non-negative integer A and one positive integer B, it’s very easy for us to calculate A Mod B. Here A Mod B means the remainder of the answer after A is divided by B. For example, 7 Mod 5 = 2, 12 Mod 3 = 0, 0 Mod 3 = 0.

In this problem, we use the following rules to express A.

(1) One non-empty string that only contains {0,1,2,3,4,5,6,7,8,9} is valid.

For example, 123, 000213, 99213. (Leading zeros is OK in this problem)

(2) If w is valid, then [w]x if valid. Here x is one integer that 0<x<10.

For example, [012]2=012012, [35]3[7]1=3535357.

(3) If w and v are valid, then wv is valid.

For example, w=[231]2 and v=1, then wv=[231]21 is valid (which is 2312311).

Now you are given A and B. Here A is express as the rules above and B is simply one integer, you are expected to output the A Mod B.

 Input

The first line of the input contains an integer T(T≤10), indicating the number of test cases.

Then T cases, for any case, only two lines.

The first line is one non-empty and valid string that expresses A, the length of the string is no more than 1,000.

The second line is one integer B(0<B<2,000,000,000).

You may assume that the length of number A in decimal notation will less than 2^63.

 Output

For each test case, output A Mod B in a single line.

 Sample Input

3[0]9[[1]2]310007[[213231414343214231]5]110007[0012]11

 Sample Output

103439430

思路 - -很简单。。字符串递归。。代码写挫了。。  也写的太慢了。。
不难的题啊。。。。。。。硬是写了几个小时。。是递归写的太弱了。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define ll __int64
using namespace std;
const int N = 2222;
char s[N];
ll MOD=10007;
int exist[N];
ll POW(ll base,ll n){
	ll ans = 1;
	while(n){
		if(n&1) (ans*=base)%=MOD;
		(base*=base)%=MOD;
		n >>=1;
	}
	return ans;
}
ll val(int i,int j){
	ll ret = 0;
	while(s[i]=='[') i++;
	while(s[j]==']') j--;
	for(;i <= j;i++){
		ret = ret * 10 + s[i]-'0';
		ret %= MOD;
	}
	return ret;
}
int weishu(ll n){
    if(!n)return 1;
    int ret=0;
    while(n){
        n /=10;
        ret++;
    }
    return ret;
}
ll Z(ll left,ll right,int w){
    if(right == 0)return 0;
    ll ret = 0;
	ll tmp = POW(10,w);
    for(ll i = 0;i < right;i++){
        ret = ret * tmp + left;
        ret %= MOD;
    }
    return ret;
}

ll digui(int l,int r,int rr,int &wei){// [[33]3]这种结构

	if(exist[r]==exist[l]){ // 此时[33]3结构
		wei = (r-l+1)*val(r+2,rr);
		return Z(val(l,r),val(r+2,rr),r-l+1);
	}else{   // 要处理[[33]3]4这种结构
	    ll ans = 0;
		int tWei = 0;
		int li,lj,rj;
		for(li = l;li <= r;li++){
            if(s[li] == '['){
                int c = 1;
                int j = li+1;
                int tmp_wei;
                while(c){
                    if(s[j]=='[')
                        c++;
                    else if(s[j]==']')
                        c--;
                    j++;
                }
                ll tt = digui(li+1,j-2,j,tmp_wei);
                ans = ans * POW(10,tmp_wei) % MOD;
                tWei += tmp_wei;
                ans = (ans+tt)%MOD;
                li = j;
            }else{
                ans = (ans * 10+ s[li]-'0')%MOD;
                tWei += 1;
            }
		}
		wei = tWei * val(r+2,rr);
        return Z(ans,val(r+2,rr),tWei);
	}
}
ll cal()
{
	int len = strlen(s);
	int count=1;
	ll ans = 0;
	for(int i = 0;i<len;i++){
		if(s[i] == '['){
			int c = 1;
			int j = i+1;
			int tmp_wei;
			while(c){
				if(s[j]=='[')
					c++;
				else if(s[j]==']')
					c--;
				j++;
			}
			ll tt = digui(i+1,j-2,j,tmp_wei);
			ans = ans * POW(10,tmp_wei) % MOD;
			ans = (ans+tt)%MOD;
			i = j;
		}else{
			ans = (ans * 10+ s[i]-'0')%MOD;
		}
	}
	return ans;
}
int main()
{
   int t;
   scanf("%d",&t);
   while(t--){
		scanf("%s",s);
		cin >> MOD;
		exist[0]=0;
		int len= strlen(s);
		for(int i = 1;i < len;i++){
            exist[i]= s[i]==']'?exist[i-1]+1:exist[i-1];
		}
		printf("%d\n",cal());
   }
   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值