POJ 1850 Code && 1496 Word Index 组合数学
题意:两道题一样,一样的代码就可以过。就是说26个字母各对应一个整数,ab对应27,ac对应28.。。。这样对应下去,需要注意的是字符串必须是升序的,即后面的字符必须比前面的字符大。思路:网上说是组合原理的应用,不过我没发现哪里用到了组合数学的知识,感觉就是一道普通的模拟题。想清楚就可以了。我做的时候是开了一个dp[27][27]的数组,dp[i][j]表示的是长度为i,以j开头的字符的序号,也就是对应的数字,并且用num[i][j]记录以长度为i,以j开头的字符有多少个。然后输入一个字符串,算就可以了。
代码:
[cpp]
//1850 1496
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
typedef long long LL;
const int N = 27;
LL dp[N][N], num[N][N];
bool fun(string ss){
bool flag = true;
for(int i = 0; i < ss.size() - 1; ++i){
if(! (ss[i+1] > ss[i] )){
flag = false;
break;
}
}
return flag;
}
void init(){
CLR(dp,0);
CLR(num,0);
for(int i = 1; i < N; ++i){
dp[1][i] = i;
num[1][i] = 1;
}
for(int i = 2; i < N; ++i){
for(int j = 1; j + i <= N; ++j){
LL sum = 0;
for(int k = 1; k + i - 1<= N; ++k)
sum += num[i-1][k];
if(j == 1)
dp[i][j] = dp[i-1][j] + sum;
else
dp[i][j] = dp[i][j-1] + num[i][j-1];
LL sum1 = 0;
for(int k = j+1; k + i - 1 <= N; ++k)
sum1 += num[i-1][k];
num[i][j] = sum1;
}
}
}
int main(){
//freopen("2.txt","w",stdout);
init();
string ss;
while(cin>>ss){
if(! fun(ss)){
printf("0\n");
continue;
}
int len = ss.size();
int x = ss[0] - 'a' + 1;
LL id = dp[len][x];
for(int i = 1; i < len; ++i){
int y = ss[i] - 'a' + 1;
x = ss[i-1] - 'a' + 1;
LL sum = 0;
for(int j = x + 1; j < y; ++j)
sum += num[len - i][j];
id += sum;
} www.zzzyk.com
printf("%lld\n",id);
}
return 0;
}
作者:wmn_wmn
补充:软件开发 , C++ ,