jzoj1207. 遥控车(二分)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanghaoxian1/article/details/82812898

1207. 遥控车

Description
平平带着韵韵来到了游乐园,看到了n辆漂亮的遥控车,每辆车上都有一个唯一的名字name[i]。韵韵早就迫不及待地想玩名字是s的遥控车。可是韵韵毕竟还小,她想象的名字可能是一辆车名字的前缀(也就是说能确定一个i,使s是name[i]的前缀),这时她就能玩第i辆车;或者是一个无中生有的名字,即s不是任何一辆车名字的前缀,这时候她什么也不能玩。
你需要完成下面的任务:
1.韵韵想了m个她想要的名字,请告诉她能玩多少次。
2.由于管理员粗心的操作,导致每辆车的摆放位置都可能出现微小的差错,原来第i辆车现在的位置可能是i-1、i、i+1中的任意一个(第1辆车的位置不可能是0,第n辆车的位置不可能是n+1)。请你计算出共有多少种可能的排列。
注:数据保证当s是name[i]的前缀时,i是唯一确定的。一辆车可以玩多次。

Input
第一行是2个正整数n、m。
接下来n行,每行1个字符串name[i],表示第i辆车的名字。
接下来m行,每行1个字符串s,表示韵韵想要的名字。

Output
第一行输出韵韵能玩的次数。
第二行输出共有多少种可能的排列。

Sample Input
4 4
Abcd
DeF
AAa
aBccc
Ab
AA
AbC
aBcc

Sample Output
3
5

Hint
【数据规模和约定】
对于题目涉及到的字符串严格区分大小写,且长度小于255。
对于20%的数据 n≤10,m≤10;
对于40%的数据 n≤1000,m≤1000;
对于100%的数据 n≤10000,m≤10000。

分析:第一问二分一下,第二问显然是个斐波那契数列。

代码

#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <iostream>
#define N 10005
using namespace std;
string s[N],c[N];
int a[N],b[N],f[N];
int n,m,l;
long long ans;
 
void fib()
{
    memset(f, 0, sizeof(f));
    int m = 0;
    for(int i = 1; i <= l + 1; i++)
	{
    	f[i] += a[i] + b[i] + m;
        m = f[i] / 10;
        f[i] %= 10;
    }
    if(f[l + 1]) l++;
    for(int i = 1; i <= l; i++) a[i] = b[i];
    for(int i = 1; i <= l; i++) b[i] = f[i];
}

bool find(int i)
{
	int l = 1, r = n, mid;
    while(l < r)
	{
       	mid = (l + r) / 2;
    	if (c[i] <= s[mid]) r = mid;
        	else l = mid + 1;
    }
    if(!s[l].find(c[i], 0)) return true;
    return false;
}
 
int main()
{
	scanf("%d%d", &n, &m);
	a[1] = 1;
	b[1] = 2;
    l = 1;
    for(int i = 1; i <= n; i++)
		cin >> s[i];
    sort(s + 1, s + n + 1);
    for(int i = 1; i <= m; i++)
	{
    	cin >> c[i];
        if (find(i)) ans++;
    }
    cout << ans << "\n";
    for (int i = 3; i <= n; i ++)
    	fib();
    for(int i = l; i >= 1; i--) cout << f[i];
}

猜你喜欢

转载自blog.csdn.net/zhanghaoxian1/article/details/82812898
今日推荐