PKU 1451 较为复杂的模拟题

题意:给定字典和每个单词的权值(表示为概率p)m对于每次查询,输出满足条件的概率最大的单词前缀。

根据题意,这题应该是用字典树做的,可惜弱菜还不怎么熟悉字典树,所以就满打满敲,模拟也可以出来。。。

#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<map>
#include<cmath>
#include<iostream>
#include <queue>
#include <stack>
#include<algorithm>
#include<set>
using namespace std;
#define inf 2147483647
#define eps 1e-8
#define LL long long
#define M 1005
#define mol 1000000007
struct node
{
   char s[105];
   int num[105];
   int v;
}p[1005];
int ok(int p1,int p2,int l)
{
   if(strlen(p[p1].s)<l+1||strlen(p[p2].s)<l+1)
	   return 0;
   for(int i=0;i<=l;i++)
	   if(p[p1].s [i]!=p[p2].s[i])
		   return 0;
   return 1;
}
int main()
{
	int t,n,m,a,Case=1;
	char ch;
	int dir[10]={0,0,3,3,3,3,3,4,3,4};
	char key[10][5]={{},{},{'a','b','c'},{'d','e','f'},{'g','h','i'},
	{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};
	scanf("%d",&t);
	while(t--)
	{
	    scanf("%d",&n);
		int i,j,k;
		for(i=0;i<n;i++)
			scanf("%s%d",p[i].s,&p[i].v);
		printf("Scenario #%d:\n",Case++);
		scanf("%d",&m);
		int count =0;
		for(i=0;i<m;i++)
		{
			count=-1;
			int vis[1005];
			memset(vis,0,sizeof(vis));
		    while(scanf("%c",&ch))
			{
			    if(ch=='1')
					break;
				if(ch>'9'||ch<'2')
					continue;
				count++;
				a=ch-'0';
				for(j=0;j<n;j++)
				{
					int flag=0;
				   for(k=0;k<dir[a];k++)
				   {
				       if(p[j].s[count]==key[a][k])
					   {
					      flag=1;
							  break;
					   }
				   }
				   if(!flag)
					   vis[j]=1;
				}
				int w=-1,pos=-1,max=-1,num=0;
				for(j=0;j<n;j++)
				{
				   if(!vis[j])
				   {
				       if(pos==-1||ok(pos,j,count))
						   num+=p[j].v ;
					   else num=p[j].v;
					   if(num>max)
					   {
					      max=num;
						  w=j;
					   }
					   pos=j;
				   }
				}
				if(pos==-1) printf("MANUALLY\n");
				else
				{
				   for(k=0;k<=count;k++)
					   printf("%c",p[w].s[k]);
				   printf("\n");
				}
			
			}
			printf("\n");
		}
		printf("\n");
	}
return 0;
}


你可能感兴趣的:(PKU 1451 较为复杂的模拟题)