字符串专题

 memory limit exceed:超出内存限制: 一般是①数组开太大②每一组的样例的初始化没初始化好。

1.使用C语言提供的函数:toupper(),tolower()

使用这两个函数需要引入头文件:#include

ASCII: A~Z:65~90,a~z:97~122

注意调用transfrom时要用头文件#include

string 类大写转小写:

 transform(strA.begin(), strA.end(), strA.begin(), ::tolower);  

string类小写转大写:

  transform(strA.begin(), strA.end(), strA.begin(), ::toupper);  

1、strcmp(str1,str2):

如果返回值 < 0,则表示 str1 小于 str2。

如果返回值 > 0,则表示 str2 小于 str1。

如果返回值 = 0,则表示 str1 等于 str2。

#include//STL reverse函数的头文件,reverse反转函数,

 find()函数

string st2("aabcbcabcbabcc");
    string str1("abc");
    cout << st2.find(str1, 2) << endl;//6   从st2的位置2(b)开始匹配,返回第一次成功匹配时匹配的串(abc)的首字符在st2中的位置,失败返回npos

stringstream类:#include,运用此方法不需要讲一群数字组成的串用空格分开

样例①


#include 
#include 
#include 
#include 
using namespace std;
int main(){
	setst;
	string str;
	while(getline(cin,str)){
		st.clear();
		if(str[0]=='#')
			break;
		stringstream strm(str);
		string tmp;
		while(strm>>tmp)
		st.insert(tmp);
		 cout<

 样例2:

#include
#include
#include
using namespace std;
int main(){
    string line;
    while(getline(cin,line)){
        int x;
        stringstream ss(line);  //建立stringstream对象,初始化流内容为line所代表的字符串
        while(ss>>x)            //从line中一次读取数字存入x
        cout<

 strtok()

①分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。

②看上面的文字叙述应该不好懂,看下面这段代码就懂了

char s[1000],a[1000][1000];

int main()
{
    while(gets(s))
    {
        if(strcmp(s,"#")==0)
            break;
        int i,j,k,n=0;
        char *p;
        p=strtok(s," ");//以空格分开
        for(i=0;p!=NULL;i++)
        {
            strcpy(a[i],p);
           // cout<

2、strncpy():

strncpy 是 C语言的库函数之一,来自 C语言标准库,定义于 string.h,char *strncpy(char *dest, const char *src, int n),把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。

3、字符串截取:

#include
#include
 
int mid(char str[],int start,int len,char strback[]);
 
int main()
{
	//char a[]="I have a dream";//初始化字符数组就不用指定它的大小
	char str[100];
	char newstr[100];//只是纯粹的申明一个字符数组变量就必须要指定一个大小
	
	gets(str);//在VS2008里面会出现警告(gets不安全。),把gets改为gets_s就不会出现警告提示了
 
 
	int m=mid(str,2,4,newstr);
	if(m)
	{
		printf("%s\n",newstr);//输出字符串,与下面的一样的效果
		//puts(newstr);
	}
	else
	{
		printf("超出字符串长度\n");//加上/n才会换行
		puts("超出字符串长度");//输出玩字符串后会自动换行
	}
	return 0;
}
int mid(char str[],int start,int len,char strback[])
{
	int l,i,k=0;
	l=strlen(str);
	if(start+len>l)
		return 0;
	for(i=start;i

[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 

kmp算法详解,next数组等等,讲的超级好

扩展KMP:具体意思我还不懂啊啊啊啊还是很难的啊 扩展kmp算法的详解,这是我唯一看懂的一个详解

const int maxn=100010;   //字符串长度最大值
int next[maxn],ex[maxn]; //ex数组即为extend数组
/*
extend数组,extend[i]表示T与S[i,n-1]的最长公共前缀,要求出所有extend[i](0<=ipo+next[po],则要从头开始匹配
            while(i+jex[po]+po则要从头开始匹配
            while(i+j

4、kmp中的next数组求最小循环节的应用

#include
#include
#include
using namespace std;
const int maxn=1000005;
int next1[maxn];
void getnext(char *s)
{
    int mp=strlen(s);
    int j=0,k=-1;
    next1[0]=-1;
    while(j

求周期性前缀HDU1358 

Sample Input
3
aaa
12
aabaabaabaab
0
Sample Output
Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4
for(int i=0; i<=n; i++)
    {
        if(next[i]==-1 || next[i]==0)   //next[i]是-1或0的忽略,说明之前没有周期性前缀
            continue;
        j = i - next[i];
        if(i%j==0)  //能整除,说明存在周期性前缀
            printf("%d %d\n",i,i/j);    //输出这个前缀的长度和周期数
    }

manacher的用法详解,讲的很清楚

HDU3068求最长回文串——用manacher法

#include 
#include 
#include
#include
#define min(a,b) ai?min(p[2*id-i],mx-i):1;
        while(s[i+p[i]]==s[i-p[i]])
            p[i]++;
        if(i+p[i]>mx)
        {
            mx=i+p[i];
            id=i;
        }
    }
}
void init()
{
    s[0]='$';
    s[1]='#';
    int i;
    for(i=0;i

HDU1238substrings

这个找字串的问题,题目大概意思就是找出所有字符串中共同拥有的一个子串,

该子串(正、逆字符)是任何一个母串的子串,求该子串的最长长度。

方法:首先找到最短的那个字符串,然后对它进行反转,再从大到小的长度对其余输入的字符串进行查找,for循环写的很巧妙

/*Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2*/
#include 
#include
#include
#include
using namespace std;
const int maxn=105;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        scanf("%d",&n);
        string s[maxn];
        int len=105;
        int pos=0;
      int  ma=0;
        for(int i=0; i>s[i];
            if(len>s[i].length())
            {
                len=s[i].length();
                pos=i;
            }

        }

        for(int i=s[pos].length(); i>=0; i--)
        {
            for(int j=0; j

字典树详解 

统计问题:https://vjudge.net/problem/HDU-1251

代码如下:注意不要用G++交,C++可以

#include 
#include
using namespace std;
struct trienode
{
    int countt;//统计单词前缀出现的次数
    trienode* nextt[26];//指向各子树的指针
    bool exist;//标记该结点处是否构成单词
    trienode():countt(0),exist(false)
    {
        for(int i=0;i<26;i++)
        {
            nextt[i]=NULL;
        }
    }
};
void trieinsert(trienode* root,string &word)
{
    trienode *node=root;
    int id;
    int len=word.size();
    int i=0;
    while(inextt[id]==NULL)
            node->nextt[id]=new trienode();
        node=node->nextt[id];
        node->countt+=1;
        i++;
    }
    node->exist=true;//单词结束,可以构成一个单词
}
int triesearch(trienode* root,string &word)
{
    trienode *node=root;
    int len=word.size();
    int i=0;
    while(inextt[id]!=NULL)
        {
            node=node->nextt[id];
            i++;
        }
        else
            return 0;
    }
    return node->countt;
}
int main()
{
    trienode *root=new trienode();
   // int flag=false;
    string word;
    while(getline(cin,word)&&word.compare("")!=0)
    {
        trieinsert(root,word);
    }
    while(cin>>word)
        cout<

例题:

给你一堆英文单词(可能有4000000个。用普通查询铁定让你TLE)。找出出现次数最多的,输出这个单词,并输出出现的次数。

思路:

如果数据范围很小,我们可以用STL里面的map映射来做,但是数据范围太大,用普通的数据结构肯定会超时,所以要考虑更优的数据结构。当然,这题也是赤裸裸的字典树应用。当然,也可以用hash来做。

#include
#include
using namespace std;
struct Dictree
{
   int count;//单词出现的次数
   struct Dictree *tire[26];//26个子节点
}*a;
void init()
{
   a = new Dictree;
   for(int i = 0;i < 26;i++)
	   a->tire[i] = NULL;//子节点指针置空
}
int insert(char str[])
{
   int len ,res;
   Dictree *head = a;//head是头指针,每次变化。但a不变,每次从头指针开始
   len = strlen(str);
   for(int i = 0;i < len;i++)
   {
       res = (int) (str[i] - 97);//下标对应字母
	   if(head->tire[res] == NULL)//没有此字母,开始新节点并初始化
	   {
	      head->tire[res] = new Dictree;
		  head = head->tire[res];//和下一个顺序不能反,先指向开辟节点,再赋值为0
		  head->count = 0;
		  for(int j = 0;j < 26;j++)
		  {
		     head->tire[j] = NULL;
		  }
	   }
	   else head = head->tire[res];
   }
   head->count++;//记录单词出现次数
   return head->count;//返回单词出现的次数
 
}
int main()
{
  int num, tmp,maxlen = 0;
  char ani[11],ans[11];
  init();
  cin>>num;
  for(int i = 0;i < num;i++)
  {
     cin>>ani;
	 tmp = insert(ani);
	 if(tmp > maxlen)
	 {
	   maxlen = tmp;
	   strcpy(ans,ani);
	 }
  }
  cout<

 但数据较少,也可以用map 

#include
#include
#include
#include
using namespace std;
 
 
int main()
{
	int n;
	char animal[11];
	map ani;
	map::iterator pos, num;
	cin>>n;
	for(int i = 0; i < n; ++i)
	{
		cin>>animal;
		ani[animal] += 1;
	}
	for(pos = ani.begin(), num = ani.begin(); pos != ani.end(); ++pos)
	{
		if(pos->second > num->second)
		{
			num = pos;
		}
	}
	cout<first<<" "<second<

 字典树练习

练习

hdu 2072 单词数

解题思路:http://blog.csdn.net/piaocoder/article/details/41902793

hdu 1671 Phone List

解题思路:http://blog.csdn.net/piaocoder/article/details/47951011

POJ 2001 Shortest Prefixes

解题思路:http://blog.csdn.net/piaocoder/article/details/47731321

POJ 2418 Hardwood Species

解题思路:http://blog.csdn.net/piaocoder/article/details/47731453

POJ 2503 Babelfish

解题思路:http://blog.csdn.net/piaocoder/article/details/47731701
 

1、问题 A: 求最长公共子串(串)

题目描述

求采用顺序结构存储的串s和串t的一个最长公共子串,若没有则输出false,若最长的有多个则输出最先出现的那一串。

输入

输入两个字符串

输出

输出公共子串

样例输入

abcdef

adbcef

样例输出 bc

这个方法好理解,不知道效率怎么样

#include
#include
#include 
#include
//#include
#include
//#include
//#include
//#include
using namespace std;
void fun();
int main()
{
	fun();
	return 0;
}
void fun()
{
	char str0[100],str1[100],dest[100];
	//gets(str0);
	cin>>str0;
	cin>>str1;
	//gets(str1);
	if(!strcmp(str0,str1))
		//puts(str1);
		cout<= 0 && j - 1 >= 0) ? arr[i - 1][ j - 1] : 0;
				arr[i][j] = str0[i] == str1[j] ? 1 + n : 0;
				if (arr[i][j] > length)
				{
					length = arr[i][j];
					end = i;
				}
			}
		}
		if(length==0)
			cout<<"false"<

  2、KMP模板题:判断pattern是否是text的子串,并返回匹配的第一个位置

/*Sample Input
2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1
Sample Output
6
-1*/
//All integers are in the range of [-1000000, 1000000].
#include 
#include
#include
using namespace std;
const int maxn=1000005;
int next1[maxn];
int text[maxn],pattern[maxn];
int ans;
void getnext(int s[],int len)
{
    int j=-1;
    next1[0]=-1;
    for(int i=1;i

3、如果是HDU2087(剪花布)这种题,应该在每次匹配成功后把j移动到0的位置

AC自动机 

hdu2222 http://acm.hdu.edu.cn/showproblem.php?pid=2222

#include 
#include
#include
#include
#include
#include
using namespace std;
struct node
{
    int cnt;//是否为该单词的最后一个节点
    node *fail;//失败指针
    node *nextt[130];
    node()
    {
        cnt=0;
        fail=0;
        memset(nextt,NULL,sizeof(nextt));
    }
};//队列,方便用BFS构造失败指针
char s[1000005];//主字符串
char keyword[55];//需要查找的单词
int head,tail;
node *root;//头节点
/*void init(node *root)
{
    root->cnt=0;
    root->fail=NULL;
    for(int i=0;i<130;i++)
        root->nextt[i]=NULL;
}*/
void build_trie(char *keyword)
{
   // node *p,*q;
   node *p=root;
    int i,v;
    int len=strlen(keyword);
    for(i=0;inextt[v]==NULL)
        {
            //q=(struct ndoe*)malloc(sizeof(node));

           // q=(struct node*)malloc(sizeof(node));
           // q=new node;
            //init(q);
            p->nextt[v]=new node();//节点链接
        }
        p=p->nextt[v];
    }
    p->cnt++;//单词最后一个节点cnt++,代表一个单词
}
void build_ac_fail(node *root)
{
    queue  que;
    root->fail=NULL;
    que.push(root);
    while(!que.empty())
    {
        node *temp=que.front();
        que.pop();
        node *p=NULL;
        for(int i=0; i<130; i++)
        {
            if(temp->nextt[i]!=NULL)
            {
                if(temp==root) temp->nextt[i]->fail=root;
                else
                {
                    p=temp->fail;
                    while(p!=NULL)
                    {
                        if(p->nextt[i]!=NULL)
                        {
                            temp->nextt[i]->fail=p->nextt[i];
                            break;
                        }
                        p=p->fail;
                    }
                    if(p==NULL)
                        temp->nextt[i]->fail=root;
                }
                que.push(temp->nextt[i]);
            }
        }
    }


}
/*void build_ac_fail(node *root)
{
    head=0,tail=0;//队列头、尾指针
    queuet[head++]=root;//先将root入队
    while(head!=tail)
    {
        node *p=NULL;
        node *temp=queuet[tail++];//弹出队头结点
        for(int i=0;i<130;i++)
        {
            if(temp->nextt[i]!=NULL)//找到实际存在的字符节点
            {
                //temp->nextt[i] 为该节点,temp为其父节点
                if(temp==root)//若是第一层中的字符节点,则把该节点指针指向root
                    temp->nextt[i]->fail=root;
                else
                    {
                        //依次回溯该节点的父节点的失败指针直到某节点的nextt[i]与该节点相同
                        //则把该节点的失败指针指向该nextt[i]节点
                        //若回溯到root都没有找到,则该节点的失败指针指向root
                        p=temp->fail;//把该节点的父节点的失败指针给p
                        while(p!=NULL)
                        {
                            if(p->nextt[i]!=NULL)
                            {
                                temp->nextt[i]->fail=p->nextt[i];
                                break;
                            }
                            p=p->fail;
                        }
                        //让该节点的失败指针也指向root
                        if(p==NULL)
                            temp->nextt[i]->fail=root;
                    }
                    queuet[head++]=temp->nextt[i];//每处理一个节点,都让该节点依次入队

            }
        }
    }
*/
int query(node *root)//匹配
{
    //i为主串指针,p为模式串指针
    int i,v,countt=0;
    node *p=root;
    int len=strlen(s);
    for(i=0;inextt[v]==NULL&&p!=root)
            p=p->fail;
        p=p->nextt[v];//找到后p指针指向该节点
        if(p==NULL)//若指针返回为空,则没有找到与之匹配的字符
            p=root;
        node *temp=p;//匹配该节点后,沿其失败指针回溯,判断其它节点是否匹配
        while(temp!=root)//匹配结束控制
        {
            if(temp->cnt>=0)//判断该节点是否被访问
            {
                countt+=temp->cnt;//由于cnt初始化为0,所以cnt>0时才统计了单词的个数
                temp->cnt=-1;//标记已访问过
            }
            else//节点已经访问,退出循环
                break;
            temp=temp->fail;//回溯,失败指针,继续寻找下一个节点
        }
    }
    return countt;
}
int main()
{
   int T,n;
   cin>>T;
   while(T--)
   {
       /*root=(struct node*)malloc(sizeof(node));
       init(root);*/
       root=new node();
       cin>>n;
       for(int i=0;i
#include 
#include
#include
#include
#include
using namespace std;
struct node
{
    int cnt;//是否为该单词的最后一个节点
    node *fail;//失败指针
    node *nextt[130];
}*queuet[500005];//队列,方便用BFS构造失败指针
char s[1000005];//主字符串
char keyword[55];//需要查找的单词
int head,tail;
node *root;//头节点
void init(node *root)
{
    root->cnt=0;
    root->fail=NULL;
    for(int i=0;i<130;i++)
        root->nextt[i]=NULL;
}
void build_trie(char *keyword)
{
    node *p,*q;
    int i,v;
    int len=strlen(keyword);
    for(i=0,p=root;inextt[v]==NULL)
        {
            //q=(struct ndoe*)malloc(sizeof(node));

            q=(struct node*)malloc(sizeof(node));
           // q=new node;
            init(q);
            p->nextt[v]=q;//节点链接
        }
        p=p->nextt[v];
    }
    p->cnt++;//单词最后一个节点cnt++,代表一个单词
}
void build_ac_fail(node *root)
{
    head=0,tail=0;//队列头、尾指针
    queuet[head++]=root;//先将root入队
    while(head!=tail)
    {
        node *p=NULL;
        node *temp=queuet[tail++];//弹出队头结点
        for(int i=0;i<130;i++)
        {
            if(temp->nextt[i]!=NULL)//找到实际存在的字符节点
            {
                //temp->nextt[i] 为该节点,temp为其父节点
                if(temp==root)//若是第一层中的字符节点,则把该节点指针指向root
                    temp->nextt[i]->fail=root;
                else
                    {
                        //依次回溯该节点的父节点的失败指针直到某节点的nextt[i]与该节点相同
                        //则把该节点的失败指针指向该nextt[i]节点
                        //若回溯到root都没有找到,则该节点的失败指针指向root
                        p=temp->fail;//把该节点的父节点的失败指针给p
                        while(p!=NULL)
                        {
                            if(p->nextt[i]!=NULL)
                            {
                                temp->nextt[i]->fail=p->nextt[i];
                                break;
                            }
                            p=p->fail;
                        }
                        //让该节点的失败指针也指向root
                        if(p==NULL)
                            temp->nextt[i]->fail=root;
                    }
                    queuet[head++]=temp->nextt[i];//每处理一个节点,都让该节点依次入队

            }
        }
    }
}
int query(node *root)//匹配
{
    //i为主串指针,p为模式串指针
    int i,v,countt=0;
    node *p=root;
    int len=strlen(s);
    for(i=0;inextt[v]==NULL&&p!=root)
            p=p->fail;
        p=p->nextt[v];//找到后p指针指向该节点
        if(p==NULL)//若指针返回为空,则没有找到与之匹配的字符
            p=root;
        node *temp=p;//匹配该节点后,沿其失败指针回溯,判断其它节点是否匹配
        while(temp!=root)//匹配结束控制
        {
            if(temp->cnt>=0)//判断该节点是否被访问
            {
                countt+=temp->cnt;//由于cnt初始化为0,所以cnt>0时才统计了单词的个数
                temp->cnt=-1;//标记已访问过
            }
            else//节点已经访问,退出循环
                break;
            temp=temp->fail;//回溯,失败指针,继续寻找下一个节点
        }
    }
    return countt;
}
int main()
{
   int T,n;
   cin>>T;
   while(T--)
   {
       root=(struct node*)malloc(sizeof(node));
       init(root);
       cin>>n;
       for(int i=0;i

hdu2896http://acm.hdu.edu.cn/showproblem.php?pid=2896

/*依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
Sample Output
web 1: 1 2 3
total: 1*/
#include 
#include
#include
#include
#include
using namespace std;
const int maxn=10010;//在hdu2896这道题中,我的初始化出现了问题
struct node
{
    int cnt;//是否为该单词的最后一个节点
    int code;
    node *fail;//失败指针
    node *nextt[130];
    node()
    {
        fail=NULL;
        code=0;
        cnt=0;
        memset(nextt,NULL,sizeof(nextt));
    }

};//队列,方便用BFS构造失败指针

//需要查找的单词

int ans[5];//标记主串中含有病毒的编号

/*void init(node *root)//我用这个函数,提交超内存
{
    root->cnt=0;
    root->code=0;
    root->fail=NULL;
    for(int i=0; i<130; i++)//注意这里是大小写字母均存在,用130 这个范围,以后如果要谜面这种情况,直接用构造函数,sizeof(nextt)
        root->nextt[i]=NULL;
}*/
void build_trie(node*root,char *keyword,int x)
{
    node *p=root;
    int i=0,v;
   int len=strlen(keyword);
   /*while(keyword[i])
    {
          v=keyword[i];
        if(p->nextt[v]==NULL)
        {
           p->nextt[v]=new node();
        }
        p=p->nextt[v];
        i++;
    }*/

   for(i=0,p=root; inextt[v]==NULL)
        {
        //q=new node;
          //  init(q);
           // p->nextt[v]=q;
            p->nextt[v]=new node();//节点链接
        }
        p=p->nextt[v];
    }
    p->code=x;
    // p->cnt=1;
    p->cnt++;//单词最后一个节点cnt++,代表一个单词
}
void build_ac_fail(node *root)
{
    queue  que;
    root->fail=NULL;
    que.push(root);
    while(!que.empty())
    {
        node *temp=que.front();
        que.pop();
        node *p=NULL;
        for(int i=0; i<130; i++)
        {
            if(temp->nextt[i]!=NULL)
            {
                if(temp==root) temp->nextt[i]->fail=root;
                else
                {
                    p=temp->fail;
                    while(p!=NULL)
                    {
                        if(p->nextt[i]!=NULL)
                        {
                            temp->nextt[i]->fail=p->nextt[i];
                            break;
                        }
                        p=p->fail;
                    }
                    if(p==NULL)
                        temp->nextt[i]->fail=root;
                }
                que.push(temp->nextt[i]);
            }
        }
    }


}
int query(node *root,char *str)
{
    int i=0,cnnt=0,index;
    node *p=root;
    while(str[i])
    {
        index=str[i];
        while(p->nextt[index]==NULL&&p!=root)
            p=p->fail;
        p=p->nextt[index];
        if(p==NULL) p=root;
        node *temp=p;
        while(temp!=root&&temp->code)
        {
            ans[cnnt]=temp->code;
            cnnt+=p->cnt;
            temp=temp->fail;
        }
        i++;
    }
    return cnnt;
}

int main()
{
    int T;
    char s[maxn];//主字符串
    char keyword[205];
    while(scanf("%d",&T)!=EOF)
    {
       node * root=new node();
       /* node *root=new node;
        init(root);*/
        for(int i=1; i<=T; i++)
        {
            scanf("%s",keyword);

            build_trie(root,keyword,i);
        }
        build_ac_fail(root);
        int sum=0;
        int M;
        scanf("%d",&M);
        for(int i=1; i<=M; i++)
        {
            scanf("%s",s);
            int flag=0;
            int num=query(root,s);
           if(num)
            {
                flag=true;
                printf("web %d:",i);
                sort(ans,ans+num);
                for(int j=0; j

POj1035 字符串处理

题意:前面是字典,后面是单词表,单词表中的单词通过替换、删除、增加一个字母能否在字典中找到,如果有,则输出 

#include 
#include 
char dic[10005][20];
char wor[55][20];
int di,dj;
int Correct(char *wor)
{
	for(int i=0;i1)
	 			return 0;
	 	}
	return 1;
}
int Dellet(char *s1,char *s2)
{
	//mistake记录两个单词中对应位置字符不相等的个数 
	int mistake=0,i,j;
	 for(i=0,j=0;i1)
	 			return 0;
	 	}
	 	else
	 	{
	 		i++; j++;
	 	}
	 }
	return 1;
}
int main()
{
	di=0; dj=0;
	while(gets(dic[di]) && dic[di][0]!='#')
		di++;
	while(gets(wor[dj]) && wor[dj][0]!='#')
		dj++;
	for(int i=0;i

 

你可能感兴趣的:(算法)