搜索小结

本文深入探讨了信息技术领域的核心内容,包括前端开发、后端开发、移动开发、游戏开发等细分技术领域,同时涉及大数据开发、AI音视频处理、测试、基础运维等多个方面。通过具体案例分析和实践指导,旨在帮助读者全面理解并掌握信息技术的最新发展和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dessert

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 60000/30000K (Java/Other)
Total Submission(s) : 10   Accepted Submission(s) : 3
Problem Description
FJ has a new rule about the cows lining up for dinner. Not only must the N (3 <= N <= 15) cows line up for dinner in order, but they must place a napkin between each pair of cows with a "+", "-", or "." on it. In order to earn their dessert, the cow numbers and the napkins must form a numerical expression that evaluates to 0. The napkin with a "." enables the cows to build bigger numbers. Consider this equation for seven cows: 
      1 - 2 . 3 - 4 . 5 + 6 . 7

This means 1-23-45+67, which evaluates to 0. You job is to assist the cows in getting dessert. (Note: "... 10 . 11 ...") will use the number 1011 in its calculation.) 
 

Input
One line with a single integer, N 
 

Output
One line of output for each of the first 20 possible expressions -- then a line with a single integer that is the total number of possible answers. Each expression line has the general format of number, space, napkin, space, number, space, napkin, etc. etc. The output order is lexicographic, with "+" coming before "-" coming before ".". If fewer than 20 expressions can be formed, print all of the expressions. 
 

Sample Input
7
 

Sample Output
1 + 2 - 3 + 4 - 5 - 6 + 7
1 + 2 - 3 - 4 + 5 + 6 - 7
1 - 2 + 3 + 4 - 5 + 6 - 7
1 - 2 - 3 - 4 - 5 + 6 + 7
1 - 2 . 3 + 4 + 5 + 6 + 7
1 - 2 . 3 - 4 . 5 + 6 . 7
6
 
#include<stdio.h>
#define MAX 20
char c[MAX],b[MAX];
int num[MAX],n,count;
char a[3]={'+','-','.'};
void dfs(int m)
{
	int i,y;
	if(m==n)
	{
		int l=1,sum=0;
		num[l]=1;
		for(i=1;i<n;i++)
		{
			if(c[i]!=a[2])
			{
				l++;
				num[l]=i+1;
				b[l-1]=c[i];
			}
			else
			{
				if(i<9)
					num[l]=num[l]*10+i+1;
				else
				num[l]=num[l]*100+i+1;
			}
		}
		y=num[1];
		for(i=1;i<=l-1;i++)
		{
			if(b[i]==a[0])
			{
				y+=num[i+1];
			}
			else
			{
				y-=num[i+1];
			}
		}
		if(y==0)
		{
			count++;
			if(count<=20)
			{
				for(i=1;i<n;i++)
				{
					printf("%d %c ",i,c[i]);
				}
				printf("%d\n",i);
			}
		}
		return ;
	}
	for(i=0;i<=2;i++)
	{
		c[m]=a[i];
		dfs(m+1);
	}
}
int main()
{
	count=0;
	scanf("%d",&n);
	dfs(1);
	printf("%d\n",count);
	return 0;
}
	
Channel Allocation

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 13   Accepted Submission(s) : 8
Problem Description
When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that every receiver has a strong signal. However, the channels used by each repeater must be carefully chosen so that nearby repeaters do not interfere with one another. This condition is satisfied if adjacent repeaters use different channels. 

Since the radio frequency spectrum is a precious resource, the number of channels required by a given network of repeaters should be minimised. You have to write a program that reads in a description of a repeater network and determines the minimum number of channels required.
 

Input
The input consists of a number of maps of repeater networks. Each map begins with a line containing the number of repeaters. This is between 1 and 26, and the repeaters are referred to by consecutive upper-case letters of the alphabet starting with A. For example, ten repeaters would have the names A,B,C,...,I and J. A network with zero repeaters indicates the end of input. 

Following the number of repeaters is a list of adjacency relationships. Each line has the form: 

A:BCDH 

which indicates that the repeaters B, C, D and H are adjacent to the repeater A. The first line describes those adjacent to repeater A, the second those adjacent to B, and so on for all of the repeaters. If a repeater is not adjacent to any other, its line has the form 

A: 

The repeaters are listed in alphabetical order. 

Note that the adjacency is a symmetric relationship; if A is adjacent to B, then B is necessarily adjacent to A. Also, since the repeaters lie in a plane, the graph formed by connecting adjacent repeaters does not have any line segments that cross. 
 

Output
For each map (except the final one with no repeaters), print a line containing the minumum number of channels needed so that no adjacent channels interfere. The sample output shows the format of this line. Take care that channels is in the singular form when only one channel is required.
 

Sample Input
2
A:
B:
4
A:BC
B:ACD
C:ABD
D:BC
4
A:BCD
B:ACD
C:ABD
D:ABC
0
 

Sample Output
1 channel needed.
3 channels needed.
4 channels needed. 
 
#include<iostream>
#include<cstring>
using namespace std;
int map[27][27],flag[27];
int n;
int same(int point)
{
	int i;
	for(i=0;i<n;i++)
	{
		if(map[i][point]==1&&flag[i]==flag[point])
			return 1;
	}
	return 0;
}
int dfs(int num,int point)
{
	if(point==n) return 1;
	for(flag[point]=1;flag[point]<=num;flag[point]++)
	{
		if(!same(point))
			return dfs(num,point+1);
	}
	return 0;
}
int main()
{
	int i,j;
	char s[27];
	
	while(cin>>n)
	{
		if(n==0)
			break;
		memset(map,0,sizeof(map));		
		memset(flag,0,sizeof(flag));
		for(i=0;i<n;i++)
		{
			cin>>s;
			for(j=2;s[j]!='\0';j++)
			{
				map[i][s[j]-'A']=map[s[j]-'A'][i]=1;
			}
		}
		for(i=1;i<=4;i++)
		{
			if(dfs(i,0))
				break;			
				
		}
		if(i==1)
			cout<<i<<" channel needed."<<endl;
		else
		{
			cout<<i<<" channels needed."<<endl;
		}
	}
	return 0;
}
#include<stdio.h>
#include<string.h>
int map[27][27],flag[27];
int n;
int same(int point)
{
	int i;
	for(i=0;i<n;i++)
	{
		if(map[i][point]==1&&flag[i]==flag[point])
			return 1;
	}
	return 0;
}
int dfs(int num,int point)
{
	if(point==n) return 1;
	for(flag[point]=1;flag[point]<=num;flag[point]++)
	{
		if(!same(point))
			return dfs(num,point+1);
	}
	return 0;
}
int main()
{
	int i,j;
	char s[27];	
	while(scanf("%d",&n),n)
	{
		memset(map,0,sizeof(map));		
		memset(flag,0,sizeof(flag));
		for(i=0;i<n;i++)
		{
			scanf("%s",s);
			for(j=2;s[j]!='\0';j++)
			{
				map[i][s[j]-'A']=map[s[j]-'A'][i]=1;
			}
		}
		for(i=1;i<=4;i++)
		{
			if(dfs(i,0))
				break;			
				
		}
		if(i==1)
			printf("%d channel needed.\n",i);
		else
		{
			printf("%d channels needed.\n",i);
		}
	}
	return 0;
}
			Sudoku

Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 23   Accepted Submission(s) : 11
Special Judge
Problem Description
Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task. 

 

Input
The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.
 

Output
For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.
 

Sample Input
1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107
 

Sample Output
143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127
 
#include<stdio.h>
#include<string.h>
int map[10][10],flag1[10][10],flag2[10][10],zb[80][2];
int dingwei(int i,int j,int k)
{
	int p,q;
	for(p=i/3*3;p<=i/3*3+2;p++)
	{
		for(q=j/3*3;q<=j/3*3+2;q++)
		{
			if(map[p][q]==k) return 0;//已经存在
		}
	}
	return 1;//还未填数;
}
int dfs(int num)//0的个数
{
	int i,j,k;
	i=zb[num][0];
	j=zb[num][1];
	if(num<0) return 1;
	for(k=1;k<=9;k++)
	{
		if(dingwei(i,j,k)&&!flag1[i][k-1]&&!flag2[j][k-1])
		{
			flag1[i][k-1]=flag2[j][k-1]=1;
			map[i][j]=k;
			if(dfs(num-1))//能否填满,能填满则符合条件
				return 1;
			flag1[i][k-1]=flag2[j][k-1]=0;//不能填满则要重新清零选择其它数填
			map[i][j]=0;
		}
	}
	return 0;//全都不符合条件
}
int main()
{
	int i,j,t,num;
	char str[10][10];
	scanf("%d",&t);
	while(t--)
	{
		memset(flag1,0,sizeof(flag1));
		memset(flag2,0,sizeof(flag2));
		num=0;
		for(i=0;i<9;i++)
		{
			scanf("%s",&str[i]);
		}
		for(i=0;i<9;i++)
		{
			for(j=0;j<9;j++)
			{
				map[i][j]=str[i][j]-'0';
				if(map[i][j]==0)
				{
					zb[num][0]=i;
					zb[num][1]=j;
					num++;
				}
				if(map[i][j])
				{
					flag1[i][map[i][j]-1]=1;//记录第i行的数
					flag2[j][map[i][j]-1]=1;//记录第j列的数
				}

			}
		}
		dfs(num-1);
		for(i=0;i<9;i++)
		{
			for(j=0;j<9;j++)
				printf("%d",map[i][j]);
			printf("\n");
		}
	}
	return 0;
}


The Settlers of Catan

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 8   Accepted Submission(s) : 3
Problem Description
Within Settlers of Catan, the 1995 German game of the year, players attempt to dominate an island by building roads, settlements and cities across its uncharted wilderness. 
You are employed by a software company that just has decided to develop a computer version of this game, and you are chosen to implement one of the game's special rules: 

When the game ends, the player who built the longest road gains two extra victory points. 
The problem here is that the players usually build complex road networks and not just one linear path. Therefore, determining the longest road is not trivial (although human players usually see it immediately). 
Compared to the original game, we will solve a simplified problem here: You are given a set of nodes (cities) and a set of edges (road segments) of length 1 connecting the nodes. 
The longest road is defined as the longest path within the network that doesn't use an edge twice. Nodes may be visited more than once, though. 

Example: The following network contains a road of length 12. 

o      o--o      o

 \    /    \    /

  o--o      o--o

 /    \    /    \

o      o--o      o--o

           \    /

            o--o

 

Input
The input will contain one or more test cases. 
The first line of each test case contains two integers: the number of nodes n (2<=n<=25) and the number of edges m (1<=m<=25). The next m lines describe the m edges. Each edge is given by the numbers of the two nodes connected by it. Nodes are numbered from 0 to n-1. Edges are undirected. Nodes have degrees of three or less. The network is not neccessarily connected. 
Input will be terminated by two values of 0 for n and m.
 

Output
For each test case, print the length of the longest road on a single line.
 

Sample Input
3 2
0 1
1 2
15 16
0 2
1 2
2 3
3 4
3 5
4 6
5 7
6 8
7 8
7 9
8 10
9 11
10 12
11 12
10 13
12 14
0 0
 

Sample Output
2
12
 
#include<stdio.h>
#include<string.h>
int max,length,n,m;
int map[100][100],flag[100][100];
void dfs(int i)
{
	int j;
	for(j=0;j<n;j++)
	{
		if(map[i][j]&&!flag[i][j]&&!flag[i][j])
		{
			flag[i][j]=flag[j][i]=1;
			length++;
			if(max<length)
				max=length;
			dfs(j);
			flag[i][j]=flag[j][i]=0;
			length--;
		}
	}
}
int main()
{
	int i,x,y;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(n==0&&m==0)
			break;
		memset(map,0,sizeof(map));
		memset(flag,0,sizeof(flag));
		for(i=0;i<m;i++)
		{
			scanf("%d%d",&x,&y);
			map[x][y]=map[y][x]=1;
		}
		max=0;
		for(i=0;i<n;i++)
		{
			length=0;
			dfs(i);
		}
		printf("%d\n",max);
	}
	return 0;
}

#include<iostream>
#include<cstring>
using namespace std;
int Max,length,n,m;
int map[100][100],flag[100][100];
void dfs(int i)
{
	int j;
	for(j=0;j<n;j++)
	{
		if(map[i][j]&&!flag[i][j]&&!flag[i][j])
		{
			flag[i][j]=flag[j][i]=1;
			length++;
			if(Max<length)
				Max=length;
			dfs(j);
			flag[i][j]=flag[j][i]=0;
			length--;
		}
	}
}
int main()
{
	int i,x,y;
	while(cin>>n>>m)
	{
		if(n==0&&m==0)
			break;
		memset(map,0,sizeof(map));
		memset(flag,0,sizeof(flag));
		for(i=0;i<m;i++)
		{
			cin>>x>>y;
			map[x][y]=map[y][x]=1;
		}
		Max=0;
		for(i=0;i<n;i++)
		{
			length=0;
			dfs(i);
		}
	  cout<<Max<<endl;
	}
	return 0;
}
Sum of Factorials

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 60000/30000K (Java/Other)
Total Submission(s) : 14   Accepted Submission(s) : 9
Problem Description
John von Neumann, b. Dec. 28, 1903, d. Feb. 8, 1957, was a Hungarian-American mathematician who made important contributions to the foundations of mathematics, logic, quantum physics,meteorology, science, computers, and game theory. He was noted for a phenomenal memory and the speed with which he absorbed ideas and solved problems. In 1925 he received a B.S. diploma in chemical engineering from Zurich Institute and in 1926 a Ph.D. in mathematics from the University of Budapest. His Ph.D. dissertation on set theory was an important contribution to the subject. At the age of 20, von Neumann proposed a new definition of ordinal numbers that was universally adopted. While still in his twenties, he made many contributions in both pure and applied mathematics that established him as a mathematician of unusual depth. His Mathematical Foundations of Quantum Mechanics (1932) built a solid framework for the new scientific discipline. During this time he also proved the mini-max theorem of GAME THEORY. He gradually expanded his work in game theory, and with coauthor Oskar Morgenstern he wrote Theory of Games and Economic Behavior (1944). 
There are some numbers which can be expressed by the sum of factorials. For example 9,9=1!+2!+3! Dr. von Neumann was very interested in such numbers. So, he gives you a number n, and wants you to tell him whether or not the number can be expressed by the sum of some factorials. 
Well, it's just a piece of cake. For a given n, you'll check if there are some xi, and let n equal to Σ1<=i<=txi!. (t >=1 1, xi >= 0, xi = xj iff. i = j). If the answer is yes, say "YES"; otherwise, print out "NO".
 

Input
You will get several non-negative integer n (n <= 1,000,000) from input file. Each one is in a line by itself. 
The input is terminated by a line with a negative integer.
 

Output
For each n, you should print exactly one word ("YES" or "NO") in a single line. No extra spaces are allowed.
 

Sample Input
9
-1
 

Sample Output
YES
 

#include<stdio.h>
int f[12];
int n;
int main()
{
	int i;	
    f[0]=1;
	for(i=1;i<11;i++)
		f[i]=f[i-1]*i;
	while(scanf("%d",&n)!=EOF)
	{
		if(n<0)
			break;
		if(n==0)
		{
			printf("NO\n");
			continue;
		}
		for(i=11;i>=0;i--)
		{
			if(n>=f[i]) n-=f[i];
		}
		if(n==0)
			printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}


Choose Your Own Adventure 

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 60000/30000K (Java/Other)

Total Submission(s) : 5   Accepted Submission(s) : 3

Problem Description
 
After reading the book Tim and Marc Kill Kenny about fifty zillion times, James decided he'd had it with choose-your-own-adventure stories. No matter what choices he made, it seemed like Kenny always fell down an abandoned mine shaft, got run over by a bus load of nuns, or was messily devoured by stray cats. James eventually found the page with the happy ending (where Kenny saves himself by trapping Tim and Marc between the pizza and the hungry programmers) by flipping through the book, but he can't figure out how to get there by following the rules. Luckily, he owns a C compiler... 

 


Input
 
Input to this problem will consist of a (non-empty) series of up to 100 data sets, each representing a choose-your-own-adventure story. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets.
 
The first line contains a single integer n indicating the number of data sets. 

A single data set has 2 components: 
1.Page Count - A line containing a single integer X, where 1 < X < 100, indicating the number of pages in the story.
 
2.Page List - A sequence of X lines, each of which represents a page from the book. Each line has the following components separated from one another by single spaces:
 ?Line type - A single character indicating what type of line this is. It will represent either a "C" choice page, or an "E" end page. Page 1 is always a choice page.
 
?Text - A string of text surrounded by double quotes. Including the quotes, this component will not exceed 256 characters. The quotes are given for input purposes only and should not be considered part of the text. The text will not contain embedded double quotes.
 
?Choices - Two positive integers from 1 to X indicating the pages where the reader can go from this page. Only choice pages have this component.
 
?Ending Type - Either the text "HAPPY" or "GRISLY". There will only be one happy ending per story, and only end pages have this component. 


 


Output
 
For each story in the input: 
1.Output a single line, "STORY #" where # is 1 for the first story, 2 for the second story, etc.
 
2.Determine the story that begins on page 1 and ends on the happy ending page. Output the text of this story, printing one "page" of text per line. Note that there is only one such story for each data set. 

 


Sample Input

2
3
C "Arrived at LSU for the contest" 2 3
E "Was devoured by sidewalk ants" GRISLY
E "Won the contest. Received glory and nachos." HAPPY
5
C "Saw a peanut" 3 5
E "Made peanut butter sandwich" HAPPY
C "Found a hammer" 4 2
E "Hit self on head with hammer, ouch!" GRISLY
E "Ate the peanut, choked on it, and died" GRISLY

  


Sample Output

STORY 1
Arrived at LSU for the contest
Won the contest. Received glory and nachos.
STORY 2
Saw a peanut
Found a hammer
Made peanut butter sandwich

  
题目大意:输入一个整数n,表示有n组测试数据,
每组第一行输入一个整数x表示该组测试一共有x页,接下来输入x行,每行表示一页,
每页或者以C开头,或者以E开头,中间用引号括起一段文字,注意第一行必须以C开头,以C开头的末尾输入两个数字a,b表示该页完后可以跳转到第a页或第b页,
以E开头的末尾输入一个单词,或者是HAPPY或者是GRISLY(有且仅有一页以HAPPY结尾),
现在要求你根据输入找出以C开头以E结尾,且E的行末为HAPPY的路径,输出路径上每一页中间引号里面的内容,不包含引号。
用队列广搜:
view plain
#include<stdio.h>
#include<string.h>
char str[150][300];
int queue[150],parent[150],pre[150],top,base,a,b;
int main()  
{  
    int t,x,i,len,count=0,j;  
    scanf("%d",&t);  
    while(t--)  
    {  
        count++;  
        scanf("%d",&x);  
        getchar();  
        for(i=1;i<=x;i++)  
            gets(str[i]); 
        queue[0]=1;  
        memset(parent,0,sizeof(parent));  
        top=base=0; 
        while(1)  
        {  
            len=strlen(str[queue[top]]);  
            if(str[queue[top]][0]=='C')  
            {  
               a=str[queue[top]][len-3]-'0';
                b=str[queue[top]][len-1]-'0';  
                if(parent[a]==0 )
                {  
                    queue[++base]=a;  
                    parent[a]=queue[top];
                }  
                if(parent[b]==0)
                {  
                    queue[++base]=b;  
                    parent[b]=queue[top];  
                }  
                top++;
            }  
            else  
            {  
                if(str[queue[top]][len-2]=='P')
					break;
                else top++;  
            }  
        }  
        memset(pre,0,sizeof(pre));  
        pre[0]=queue[top]; 
        i=1;  
        while(1)
        {  
            pre[i]=parent[pre[i-1]];  
            if(pre[i]==0)  
                break;  
            else i++;  
        }  
        j=i-1;  
        printf("STORY %d\n",count);  
        for(;j>=0;j--)  
        {  
            for(i=3;str[pre[j]][i]!='"';i++)  
                printf("%c",str[pre[j]][i]);  
            printf("\n");  
        }  
    }  
    return 0;  
}  


#include<stdio.h>  
#include<string.h>  
char str[150][300];//原来的数组名为story,结果不能正常运行,story是系统保留字么?知道的回复一下  
int queue[150],pre[150],re[150],ff,tt,aa,bb;//pre[i]存第i行的祖先  
int main()  
{  
    int t,x,i,len,count=0,j;  
    scanf("%d",&t);  
    while(t--)  
    {  
        count++;  
        scanf("%d",&x);  
        getchar();  
        for(i=1;i<=x;i++)  
            gets(str[i]);//读入内容  
        queue[0]=1;//第一行入队  
        memset(pre,0,sizeof(pre));  
        ff=tt=0;//ff表示对头tt表示结尾  
        while(1)  
        {  
            len=strlen(str[queue[ff]]);  
            if(str[queue[ff]][0]=='C')  
            {  
                aa=str[queue[ff]][len-3]-'0';//取出后面的数字  
                bb=str[queue[ff]][len-1]-'0';  
                if(pre[aa]==0)//其祖先为0,表示还未入队,则把它如队  
                {  
                    queue[++tt]=aa;  
                    pre[aa]=queue[ff];//记录其祖先为当前行号  
                }  
                if(pre[bb]==0)//同上  
                {  
                    queue[++tt]=bb;  
                    pre[bb]=queue[ff];  
                }  
                ff++;//当前行出队  
            }  
            else  
            {  
                if(str[queue[ff]][len-2]=='P')//如果是以HAPPY结束,直接跳出  
                    break;  
                else ff++;  
            }  
        }  
        memset(re,0,sizeof(re));  
        re[0]=queue[ff];//最后一个的行号  
        i=1;  
        while(1)//回溯寻找路径  
        {  
            re[i]=pre[re[i-1]];  
            if(re[i]==0)  
                break;  
            else i++;  
        }  
        j=i-1;  
        printf("STORY %d\n",count);  
        for(;j>=0;j--)  
        {  
            for(i=3;str[re[j]][i]!='"';i++)  
                printf("%c",str[re[j]][i]);  
            printf("\n");  
        }  
    }  
    return 0;  
}  
用栈深搜:
看了一位仁兄的递归深搜(下面附上),于是就练习了一下用栈深搜。
view plain
#include<stdio.h>  
#include<string.h>  
struct  
{  
    char c,text[260],end[10];  
    int a,b;  
}pag[102];//存每页的内容,c页类型;text页内容 ;end结局;a、b两个指向  
struct  
{  
    int num[150],top;  
}zhan;//栈  
int x;  
int fang(int a)//检查是否被访问过,防止出现循环  
{  
    int i;  
    for(i=1;i<zhan.top;i++)  
        if(a==zhan.num[i])  
            return 1;  
    return 0;  
}  
void shuru()//输入  
{  
    int k,j;  
    scanf("%d",&x);  
    for(j=1;j<=x;j++)  
    {  
        getchar();  
        pag[j].c=getchar();  
        getchar();  
        getchar();  
        for(k=0;1;k++)  
        {  
            pag[j].text[k]=getchar();  
            if(pag[j].text[k]=='"')  
            {  
                pag[j].text[k]=0;  
                break;  
            }  
        }  
        getchar();  
        if(pag[j].c=='C')  
        {  
            scanf("%d%d",&pag[j].a,&pag[j].b);  
        }  
        else  
        {  
            scanf("%s",pag[j].end);  
        }  
    }  
}  
void dfs()//深搜  
{  
    zhan.top=-1;  
    memset(zhan.num,0,sizeof(zhan.num));  
    zhan.num[++zhan.top]=1;  
    while(1)  
    {  
        if(fang(zhan.num[zhan.top]))  
        {  
            zhan.top--;  
        }  
        if(pag[zhan.num[zhan.top]].c=='E')  
        {  
            if(pag[zhan.num[zhan.top]].end[0]=='H')  
                break;  
            else  
            {  
                zhan.top--;  
            }  
        }  
        else  
        {  
            if(0==zhan.num[zhan.top+1])//若上一栈为零,说明本栈第一次访问,将a入栈  
            {  
                zhan.top++;  
                zhan.num[zhan.top]=pag[zhan.num[zhan.top-1]].a;  
            }  
            else if(pag[zhan.num[zhan.top]].a==zhan.num[zhan.top+1])//若上一栈为a,即a被访问过,则入栈b  
            {  
                zhan.top++;  
                zhan.num[zhan.top]=pag[zhan.num[zhan.top-1]].b;  
            }  
            else//否则,a、b都被访问过,该页行不通,出栈  
            {  
                zhan.top--;  
            }  
        }  
    }  
}  
void shuchu(int i)//从栈底到栈顶就是访问路线,依次输出  
{  
    printf("STORY %d\n",i);  
    for(i=0;i<=zhan.top;i++)  
    {  
        puts(pag[zhan.num[i]].text);  
    }  
}  
int main()  
{  
    int t,i;  
    scanf("%d",&t);  
    for(i=1;i<=t;i++)  
    {  
        shuru();  
        dfs();  
        shuchu(i);  
    }  
    return 0;   
}  
用递归深搜:
view plain
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
  
struct story  
{  
    char ch;  
    char text[260];  
    int ch1,ch2;  
    char end[10];  
}st[102];  
  
int t,n,pos,flag;  
int mark[102];  
int ans[102];  
  
void solve(int num);  
  
void dfs(int p,int d);  
  
int main()  
{  
    int i,j,k;  
    scanf("%d",&t);  
    for(i=0;i<t;i++)  
    {  
        scanf("%d",&n);    
        for(j=0;j<n;j++)  
        {  
            getchar();  
            scanf("%c",&st[j].ch);  
            if(st[j].ch=='C')  
            {  
                getchar();  
                st[j].text[0]=getchar();  
                for(k=1;;k++)  
                {  
                    st[j].text[k]=getchar();  
                    if(st[j].text[k]=='"')  
                        break;  
                }  
                scanf("%d%d",&st[j].ch1,&st[j].ch2);  
            }  
            else  
            {  
                getchar();  
                st[j].text[0]=getchar();  
                for(k=1;;k++)  
                {  
                    st[j].text[k]=getchar();  
                    if(st[j].text[k]=='"')  
                        break;  
                }  
                scanf("%s",st[j].end);  
            }  
        }  
        solve(i+1);  
    }  
    return 0;  
}  
  
void solve(int num)  
{  
    int i,j;  
    memset(mark,0,sizeof(mark));  
    flag=0;  
    dfs(0,0);  
    printf("STORY %d\n",num);  
    for(i=0;i<=pos;i++)  
    {  
        for(j=1;;j++)  
        {  
            if(st[ans[i]].text[j]=='"')  
                break;  
            printf("%c",st[ans[i]].text[j]);  
        }  
        printf("\n");  
    }  
}  
  
void dfs(int p,int d)  
{  
    if(flag)  
        return ;  
    if(st[p].ch=='E')  
    {  
        if(!strcmp(st[p].end,"HAPPY"))  
        {  
            flag=1;  
            ans[d]=p;  
            pos=d;  
        }  
        else  
            return ;  
    }  
    else  
    {  
        if(!mark[st[p].ch1])  
        {  
            mark[st[p].ch1]=1;  
            dfs(st[p].ch1-1,d+1);  
            if(flag)  
            {  
                ans[d]=p;  
                return;  
            }  
        }  
        if(!mark[st[p].ch2])  
        {  
            mark[st[p].ch2]=1;  
            dfs(st[p].ch2-1,d+1);  
            if(flag)  
            {     
                ans[d]=p;  
                return;  
            }  
        }  
    }  
}  
T9 

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)

Total Submission(s) : 8   Accepted Submission(s) : 3

Problem Description
 
Background 

A while ago it was quite cumbersome to create a message for the Short Message Service (SMS) on a mobile phone. This was because you only have nine keys and the alphabet has more than nine letters, so most characters could only be entered by pressing one key several times. For example, if you wanted to type "hello" you had to press key 4 twice, key 3 twice, key 5 three times, again key 5 three times, and finally key 6 three times. This procedure is very tedious and keeps many people from using the Short Message Service.
 
This led manufacturers of mobile phones to try and find an easier way to enter text on a mobile phone. The solution they developed is called T9 text input. The "9" in the name means that you can enter almost arbitrary words with just nine keys and without pressing them more than once per character. The idea of the solution is that you simply start typing the keys without repetition, and the software uses a built-in dictionary to look for the "most probable" word matching the input. For example, to enter "hello" you simply press keys 4, 3, 5, 5, and 6 once. Of course, this could also be the input for the word "gdjjm", but since this is no sensible English word, it can safely be ignored. By ruling out all other "improbable" solutions and only taking proper English words into account, this method can speed up writing of short messages considerably. Of course, if the word is not in the dictionary (like a name) then it has to be typed in manually using key repetition again.
 


Figure 8: The Number-keys of a mobile phone.
 

More precisely, with every character typed, the phone will show the most probable combination of characters it has found up to that point. Let us assume that the phone knows about the words "idea" and "hello", with "idea" occurring more often. Pressing the keys 4, 3, 5, 5, and 6, one after the other, the phone offers you "i", "id", then switches to "hel", "hell", and finally shows "hello".
 

Problem 

Write an implementation of the T9 text input which offers the most probable character combination after every keystroke. The probability of a character combination is defined to be the sum of the probabilities of all words in the dictionary that begin with this character combination. For example, if the dictionary contains three words "hell", "hello", and "hellfire", the probability of the character combination "hell" is the sum of the probabilities of these words. If some combinations have the same probability, your program is to select the first one in alphabetic order. The user should also be able to type the beginning of words. For example, if the word "hello" is in the dictionary, the user can also enter the word "he" by pressing the keys 4 and 3 even if this word is not listed in the dictionary.
 


Input
 
The first line contains the number of scenarios. 

Each scenario begins with a line containing the number w of distinct words in the dictionary (0<=w<=1000). These words are iven in the next w lines in ascending alphabetic order. Every line starts with the word which is a sequence of lowercase letters from the alphabet without whitespace, followed by a space and an integer p, 1<=p<=100, representing the probability of that word. No word will contain more than 100 letters.
 
Following the dictionary, there is a line containing a single integer m. Next follow m lines, each consisting of a sequence of at most 100 decimal digits 2, followed by a single 1 meaning "next word".

 


Output
 
The output for each scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1.
 
For every number sequence s of the scenario, print one line for every keystroke stored in s, except for the 1 at the end. In this line, print the most probable word prefix defined by the probabilities in the dictionary and the T9 selection rules explained above. Whenever none of the words in the dictionary match the given number sequence, print "MANUALLY" instead of a prefix.
 
Terminate the output for every number sequence with a blank line, and print an additional blank line at the end of every scenario.

 


Sample Input

2
5
hell 3
hello 4
idea 8
next 8
super 3
2
435561
43321
7
another 5
contest 6
follow 3
give 13
integer 6
new 14
program 4
5
77647261
6391
4681
26684371
77771
 


Sample Output

Scenario #1:
i
id
hel
hell
hello

i
id
ide
idea


Scenario #2:
p
pr
pro
prog
progr
progra
program

n
ne
new

g
in
int

c
co
con
cont
anoth
anothe
another

p
pr
MANUALLY
MANUALLY
 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define PI 110
#define MAX 26
struct node
{
    int num;
    struct node *next[MAX];
};
int ans,dir[11]={0,0,0,3,6,9,12,15,19,22,26},len,k,max[PI];//dir[]记录手机上的每个数字所表示的字母,map[]记录每一层的最大概率
char st[PI],map[PI][PI],adj[PI];
struct node *NewTrie()
{
    int i;
    struct node *temp=(struct node*)malloc(sizeof(struct node));
    temp->num=1;
    for(i=0;i<MAX;i++)
        temp->next[i]=NULL;
    return temp;
}//初始化。。

void Insert(struct node *p,char s[])
{
    int i,len1;
    struct node *temp=p;
    len1=strlen(s);
    for(i=0;i<len1;i++)
    {
        if(temp->next[s[i]-'a']==NULL)
		{
			temp->next[s[i]-'a']=NewTrie();
			temp->next[s[i]-'a']->num+=(ans-1);
		}
        else 
			temp->next[s[i]-'a']->num+=ans;
        temp=temp->next[s[i]-'a'];    }

}//插入

void updata(struct node *p,int step)
{

    struct node *temp=p;
	int begin,end,j;
    begin=dir[st[step]-'0'];
    end=dir[st[step]-'0'+1];
     for(j=begin;j<end;j++)
        {

            if(temp->next[j]==NULL) continue;
            k++;
            adj[k]=j+'a';
            if(temp->next[j]->num > max[step])
            {
                max[step] = temp->next[j]->num;
                adj[k+1]=0;
                strcpy(map[step],adj);
            }
            if(step!=len-1) updata(temp->next[j],step+1);
            k--;
        }
}//深搜一遍

int main()
{

   struct node *p;
    int i,j,n,m,count,t;
    char str[105];
    scanf("%d",&count);
    for(t=1;t<=count;t++)
    {
        scanf("%d",&n);
        p=NewTrie();
        while(n--)
        {

            scanf("%s %d",str,&ans);
            Insert(p,str);
        }       
		scanf("%d",&m);
        printf("Scenario #%d:\n",t);
        while(m--)
        {

            scanf("%s",st);
            len=strlen(st);
            len--;
            k=-1;     
			memset(max,-1,sizeof(max));
            updata(p,0);
            for(i=0;i<len;i++)
            {
                if(max[i]!=-1) printf("%s\n",map[i]);
                else 
					break;
            }

            for(j=i;j<len;j++)
                printf("MANUALLY\n");
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/hehaitao/archive/2011/11/21/2258164.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值