• hihocoder 1260


    之前做过的oj, acm题目忘了很多了, 又要开始要刷题了, go on!

    #1260 : String Problem I

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    我们有一个字符串集合S,其中有N个两两不同的字符串。

    还有M个询问,每个询问给出一个字符串w,求有多少S中的字符串可以由w添加恰好一个字母得到。

    字母可以添加在包括开头结尾在内的任意位置,比如在"abc"中添加"x",就可能得到"xabc", "axbc", "abxc", "abcx".这4种串。

    输入

    第一行两个数N和M,表示集合S中字符串的数量和询问的数量。

    接下来N行,其中第i行给出S中第i个字符串。

    接下来M行,其中第i行给出第i个询问串。

    所有字符串只由小写字母构成。

    数据范围:

    N,M<=10000。

    S中字符串长度和<=100000。

    所有询问中字符串长度和<=100000。

    输出

    对每个询问输出一个数表示答案。

    样例输入
    3 3
    tourist
    petr
    rng
    toosimple
    rg
    ptr
    样例输出
    0
    1
    1

    二分查找,在大型数组中很常用。

    #include <cstdio>  
    #include <iostream>
    #include <cstring> 
    #include <cstdlib> 
    #include <string> 
    #include <cmath> 
    using namespace std; 
    const int maxn = 10005; 
    
    struct Node{
    	int len; 
    	string s;
    }nd[maxn]; 
    int n,m; 
    
    int Match(const string &s1, const string &s2){
    	bool isPlus = true; 
    	int j = 0; 
    	for(int i=0; i<s1.length(); i++){
    		if(s1[i] != s2[j]){
    			if(isPlus){
    				isPlus = false; 
    			}else{
    				return false; 
    			}
    		}else{
    			j++; 
    		}
    	}
    	return true; 
    }
    
    int cmp(const void* a, const void* b){
    	Node* aa = (Node *)a; 
    	Node* bb = (Node *)b; 
    	return aa->len - bb->len; 
    }
    
    int main(){
    	freopen("in.txt", "r", stdin); 
    
    	int i,j, mid, left, right, target_len, test_start, cnt; 
    	string target; 
    	scanf("%d %d", &n, &m ); 
    	getchar(); 
    	for(int i=0; i<n; i++){
    		cin>>nd[i].s;
    		nd[i].len = nd[i].s.length();  
    	}
    	qsort(nd, n, sizeof(nd[0]), cmp); 
    	for(i=0; i<m; i++){
    		cin>>target; 
    		target_len = target.length() + 1; 
    		left = 0; right = n-1; 
    		test_start = -1; 
    		while(left <= right){
    			mid = left + (right - left)/2; 
    			if(nd[mid].len == target_len){
    				j = mid-1; 
    				while(j>=0 && nd[j].len == nd[mid].len){
    					j--; 
    				}
    				test_start = j + 1; 
    				break; 
    			}else if(nd[mid].len > target_len){
    				right = mid - 1; 
    			}else{
    				left = mid + 1; 
    			}
    		}
    		if(test_start == -1){
    			printf("%d
    ", 0);
    		}else{
    			cnt = 0; 
    			for(j=test_start; nd[j].len == target_len; j++){
    				if(Match(nd[j].s, target)){
    					cnt++; 
    				}
    			}
    			printf("%d
    ", cnt);
    		}
    	}
    	return 0; 
    }
    

      

  • 相关阅读:
    Java多线程 ReadWriteLock、StampedLock用法
    Java多线程基础
    Java中创建多线程
    Java中多线程同步
    Java多线程 synchronized与ReentrantLock用法
    Linux6配置bond链路聚合
    Bash Shell命令流程
    location uri 添加 / 和不添加 / 的区别?
    Nginx负载均衡健康检查nginx_upstream_check_module
    Zabbix4.0源码安装基于LNMP
  • 原文地址:https://www.cnblogs.com/zhang-yd/p/5774420.html
Copyright © 2020-2023  润新知