#include<stdio.h>
#include<string.h>
#include<algorithm>
int e[110][110],culture[110][110],country[110],visit[110];//国家和文化的邻接矩阵
int N,K,M,S,T,learn[110],ans;
int judge(int x,int y)//判断学过的文化和x国家有冲突没有
{
if(culture[ country[y] ][ country[x] ])return 0;
if(culture[ country[T] ][ country[y] ])return 0;//如果终点国家排斥
for(int i=1;i<=learn[0];++i)
{
if(culture[learn[y]][country[i]])return 0;
}
return 1;
}
int dfs(int deep,int dis)
{
if(ans!=-1 && dis>=ans)return 0;//剪枝操作
if(deep==T)
{
ans=dis;//由于上一句的原因 那么能进来的肯定是比较小的距离
return 1;
}
for(int i=1;i<=N;++i)//遍历的邻边
{
if(deep==i)continue;
if(visit[i]==0 && judge(deep,i))//如果学过的文化和他没有冲突
{
visit[i]=1;
learn[0]++;
learn[learn[0]]=country[i];
dfs(i,dis+e[deep][i]);//递归
learn[0]--;
visit[i]=0;
}
}
return 1;
}
int main()
{
scanf("%d %d %d %d %d",&N,&K,&M,&S,&T);
for(int i=1;i<=N;++i)
scanf("%d",&country[i]);
for(int i=1;i<=K;++i)
for(int j=1;j<=K;++j)
scanf("%d",&culture[i][j]);
for(int i=1;i<=N;++i)
for(int j=1;j<=N;++j)
e[i][j]=9999;//对于题目来说 足够了
for(int i=1;i<=M;++i)
{
int u,v,d;
scanf("%d %d %d",&u,&v,&d);
if(!culture[country[v]][country[u]] && country[u]!=country[v])
e[u][v]=std::min(e[u][v],d);//这个顺序别搞反了,应该是你的国家不排斥我 我就可以过去,尽管 我排斥你
if(!culture[country[u]][country[v]] && country[u]!=country[v])
e[v][u]=std::min(e[v][u],d);
}
learn[0]=1;//存储已经学过的
learn[1]=country[S];
ans=-1;
memset(visit,0,sizeof(visit));
visit[S]=1;
dfs(S,0);
printf("%d\n",ans);
return 0;
}
32 网络警察
作者: Turbo 时间限制: 1S 章节: 基本练习(字符串)
问题描述 :
作为一名网络警察,你的任务是监视电子邮件,看其中是否有一些敏感的关键词。不过,有些狡猾的犯罪嫌疑人会改变某些单词的字母顺序,以逃避检查。请编写一个程序,发现这种调整过顺序的关键词。
输入说明 :
输入有两行,第一行是关键词列表,第二行是待检查的句子。
单词全部为小写,单词之间以一个空格分隔,每一行的单词个数不限
输出说明 :
输出为在该句子中所找到的经过顺序调整的关键词
按照在关键词列表中的先后顺序输出
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return *(char *)a - *(char *)b;
}
int main()
{
char key[2020][20],str[2020],c;
int i=0,j=0,flag[2020];//表示关键词是否出现过
while((c=getchar()) && c!='\n')
{
if(c