1. 程式人生 > >jzoj1207. 遙控車(二分)

jzoj1207. 遙控車(二分)

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];
}