AOJ : 2209 - UTF-8
問題概要
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=2209
日本語なので, 説明省略.
アルゴリズム
動的計画法で解けます.
- dp[0] = 1
- dp[i] =
- dp[i-1] * i-1バイト目から1バイト列のパターン数 +
- dp[i-2] * i-2バイト目から2バイト列のパターン数 +
- dp[i-3] * i-3バイト目から3バイト列のパターン数 +
- dp[i-4] * i-4バイト目から4バイト列のパターン数
プログラム
#define MOD 1000000LL typedef unsigned long long ll; int n; ll dp[1002]; string s[1002]; string utf[4][4] = { {"0xxxxxxx","","",""}, {"110yyyyx","10xxxxxx","",""}, {"1110yyyy","10yxxxxx","10xxxxxx",""}, {"11110yyy","10yyxxxx","10xxxxxx","10xxxxxx"} }; ll check(int idx,int len){ ll res = 1; int xcnt = 0; //ビットパターンでyの位置で, 入力列がxになっている数 int onecnt = 0; //ビットパターンでyの位置で, 入力列が1になっている数 for(int i=0;i<len;i++){ for(int j=0;j<8;j++){ char cu = utf[len-1][i][j]; char cs = s[idx+i][j]; if(cu == '0' || cu == '1'){ if(cs != 'x' && cu != cs) return 0; } else if(cu == 'x'){ if(cs == 'x') res = (res * 2) % MOD; } else{ if(cs == 'x') xcnt++; else if(cs == '1') onecnt++; } } } if(len == 1) return res; if(onecnt==0 && xcnt==0) return 0; if(onecnt == 0) res = (res * ((1<<xcnt) - 1)) % MOD; else res = (res * (1<<xcnt)) % MOD; return res; } int main(void){ while(cin>>n,n){ for(int i=0;i<n;i++) cin>>s[i]; memset(dp,0,sizeof(dp)); dp[0] = 1; for(int i=0;i<n;i++){ for(int j=1;j<=4;j++){ if(i+j > n) break; ll pat = check(i,j); if(pat == 0) continue; dp[i+j] = (dp[i+j] + dp[i] * pat) % MOD; } } cout<<dp[n]<<endl; } return 0; }