A - 变形课
http://acm.hdu.edu.cn/showproblem.php?pid=1181
Harry已经将他所会的所有咒语都列成了一个表,他想让你帮忙计算一下他是否能完成老师的作业,将一个B(ball)变成一个M(Mouse),你知道,如果他自己不能完成的话,他就只好向Hermione请教,并且被迫听一大堆好好学习的道理.
so soon river goes them got moon begin big 0
Yes.Harry 可以念这个咒语:"big-got-them".HintHint
#include<stdio.h>
#include<string.h>
#define N 5000
#include<algorithm>
using namespace std;
char ch[N][N];
int use[N];
int F,n;
void dfs(int x)
{
int j;
int l=strlen(ch[x]);
if(ch[x][l-1]=='m')
{
F=1;
return ;
}
for(j=0;j<n;j++)
{
if(ch[x][l-1]==ch[j][0]&&use[j]==0)
{
use[j]=1;
dfs(j);
use[j]=0;
}
}
}
int main()
{
while(~scanf("%s",ch[0]))
{
int i;
int flag=0;
F=0;n=1;
memset(use,0,sizeof(use));
while(1)
{
scanf("%s",ch[n]);
int l=strlen(ch[n]);
if(ch[n][l-1]=='m')
flag=1;
if(ch[n][0]=='0')
break;
n++;
}
if(!flag)
printf("No.\n");
else
{
for(i=0;i<n;i++)
{
if(ch[i][0]=='b')
dfs(i);
}
if(F)
printf("Yes.\n");
else
printf("No.\n");
}
}return 0;
}
B - Sticks
http://acm.hdu.edu.cn/showproblem.php?pid=1455
Problem Description
9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
6 5
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#define N 100
using namespace std;
int vis[N],a[N],n;
int cmp(const void *a,const void *b)
{
return *(int *)b-*(int *)a;
}
int dfs(int len,int remains_len,int num)
{
int i;
if(remains_len==0&&num==0)
{ return len;}
if(remains_len==0)
{ remains_len=len;}
for(i=0;i<n;i++)
{
if(vis[i]==1)
continue;
if(remains_len>=a[i])
{
vis[i]=1;
if(dfs(len,remains_len-a[i],num-1))
return len;
vis[i]=0;
if(a[i]==remains_len||len==remains_len)
break;
while(a[i]==a[i+1])
i++;
}
}
return 0;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
int sum=0;
int len,k;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
qsort(a,n,sizeof(int),cmp);
for(len=a[0];len<=sum;len++)
{
memset(vis,0,sizeof(vis));
if(sum%len==0)
{
k=dfs(len,0,n);
if(k)
break;
}
}
printf("%d\n",k);
}
return 0;
}
C - Red and Black
http://acm.hdu.edu.cn/showproblem.php?pid=1312
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
'.' - a black tile
'#' - a red tile
'@' - a man on a black tile(appears exactly once in a data set)
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 11 9 .#......... .#.#######. .#.#.....#. .#.#.###.#. .#.#..@#.#. .#.#####.#. .#.......#. .#########. ........... 11 6 ..#..#..#.. ..#..#..#.. ..#..#..### ..#..#..#@. ..#..#..#.. ..#..#..#.. 7 7 ..#.#.. ..#.#.. ###.### ...@... ###.### ..#.#.. ..#.#.. 0 0
45 59 6 13
#include<stdio.h>
#include<string.h>
int a[21][21];
int book[21][21],n,m,sum;
void dfs(int x,int y)
{
int next[4][2]={ {0,1},{1,0},{0,-1},{-1,0}};
int k,tx,ty;
for(k=0;k<=3;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<0||tx>n||ty<0||ty>m)
continue;
if(a[tx][ty]>0&&book[tx][ty]==0)
{
sum++;
book[tx][ty]=1;
dfs(tx,ty);
}
}
return ;
}
int main()
{
int i,j,startx,starty;
char str[21][21];
while(scanf("%d%d",&m,&n),(n||m))
{
memset(str,'\0',sizeof(str));
memset(book,0,sizeof(book));
memset(a,-1,sizeof(a));
for(i=0; i<n; i++)
{
scanf("%s",str[i]);
}
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(str[i][j]=='@')
{
startx=i;
starty=j;
a[i][j]=1;
}
if(str[i][j]=='#')
{
a[i][j]=0;
}
if(str[i][j]=='.')
{
a[i][j]=1;
}
}
}
book[startx][starty]=1;
sum=1;
dfs(startx,starty);
printf("%d\n",sum);
}
return 0;
}
D - Square
http://acm.hdu.edu.cn/showproblem.php?pid=1518
3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5
yes no yes
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=100;
int n,m,len[maxn],sum;
int vis[maxn],flag;
void dfs(int now,int length,int pos)
{
if(now==5)
{
flag=1;
return ;
}
if(length==sum/4)
{
dfs(now+1,0,0);
if(flag)
return ;
}
for(int i=pos;i<m;i++)
{
if(length+len[i]>sum)
{
return ;
}
if(!vis[i]&&length+len[i]<=sum/4)
{
vis[i]=1;
dfs(now,length+len[i],i+1);
if(flag)
return ;
vis[i]=0;
}
}
}
int main()
{
scanf("%d",&n);
while(n--)
{
sum=0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d",&len[i]);
sum+=len[i];
}
sort(len,len+m);
if((sum%4!=0)||(len[m-1]>sum/4))
{
printf("no\n");
}
else
{
memset(vis,0,sizeof(vis));
flag=0;
dfs(1,0,0);
if(flag)
printf("yes\n");
else
printf("no\n");
}
}return 0;
}
F - Prime Ring Problem
http://acm.hdu.edu.cn/showproblem.php?pid=1016
Note: the number of first circle should always be 1.
![](https://i-blog.csdnimg.cn/blog_migrate/427b1dd2282412709d583cc17eda983e.gif)
You are to write a program that completes above process.
Print a blank line after each case.
6 8
Case 1: 1 4 3 2 5 6 1 6 5 2 3 4 Case 2: 1 2 3 8 5 6 7 4 1 2 5 8 3 4 7 6 1 4 7 6 5 8 3 2 1 6 7 4 3 8 5 2
#include<stdio.h>
#include<string.h>
int a[50],x[50],n,book[50];
void solve()
{ int i,k=0;
for(i=2;i<50;i++)
{
if(x[i]==0)
{
int j;
for(j=2*i;j<50;j+=i)
{x[j]=2;}
x[i]=1;
}
}
}
void dfs(int t)
{
int i;
if(t==n+1&&x[a[1]+a[n]]==1)
{
for(i=1;i<n;i++)
{
printf("%d ",a[i]);
}printf("%d\n",a[i]);
return ;
}
for(i=2;i<=n;i++)
{
if(!book[i]&&x[a[t-1]+i]==1)
{
a[t]=i;
book[i]=1;
dfs(t+1);
book[i]=0;
}
}
}
int main()
{
int k=1;
a[1]=1;
solve();
while(~scanf("%d",&n))
{
memset(book,0,sizeof(book));
printf("Case %d:\n",k++);
dfs(2);
printf("\n");
}return 0;
}
G - 全排列
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1384
输入一个字符串S(S的长度 <= 9,且只包括0 - 9的阿拉伯数字)
输出S所包含的字符组成的所有排列
1312
1123 1132 1213 1231 1312 1321 2113 2131 2311 3112 3121 3211
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int vis[15],a[15],b[15];
char c[15];
int len;
void dfs(int t)
{
int i;
if(t==len)
{
for(i=0; i<len; i++)
{
printf("%d",b[i]);
}
printf("\n");
return ;
}
else
{
for(i=0; i<len; i++)
{
if(!vis[i])
{
vis[i]=1;
b[t]=a[i];
dfs(t+1);
vis[i]=0;
while(i-1<len&&a[i+1]==a[i])i++;
}
}
}
}
int main()
{
int i;
scanf("%s",c);
len=strlen(c);
for(i=0; i<len; i++)
{
a[i]=c[i]-'0';
}
sort(a,a+len);
memset(vis,0,sizeof(vis));
dfs(0);
return 0;
}
H - 畅通工程
http://acm.hdu.edu.cn/showproblem.php?pid=1863
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
3 ?
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int inf=0x3f3f3f3f;
int G[105][105],vis[105],dis[105];
void prim()
{
int i,j,k,minz,ans=0;
for(i=1;i<=m;i++)
{
dis[i]=G[1][i];
}
vis[1]=1;
for(i=2;i<=m;i++)
{
minz=inf;k=-1;
for(j=1;j<=m;j++)
{
if(!vis[j]&&minz>dis[j])
{
minz=dis[j];
k=j;
}
}
if(k==-1)
{
printf("?\n");
return ;
}
vis[k]=1;
ans+=minz;
for(j=1;j<=m;j++)
{
if(!vis[j]&&dis[j]>G[k][j])
{
dis[j]=G[k][j];
}
}
}
printf("%d\n",ans);
return ;
}
int main()
{
while(~scanf("%d%d",&n,&m),n)
{
memset(vis,0,sizeof(vis));
memset(G,inf,sizeof(G));
for(int i=0;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(G[a][b]>c)
G[a][b]=G[b][a]=c;
}
prim();
}
return 0;
}
http://poj.org/problem?id=2485
Description
Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.
The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.
Input
The first line of each case is an integer N (3 <= N <= 500), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 65536]) between village i and village j. There is an empty line after each test case.
Output
Sample Input
1 3 0 990 692 990 0 179 692 179 0
Sample Output
692
Hint
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int n;
int vis[550],dis[550],G[550][550];
void prim()
{
int i,j,k,minz,ans=-1;
for(i=1;i<=n;i++)
{
dis[i]=G[1][i];
}
vis[1]=1;
for(i=2;i<=n;i++)
{
k=-1;minz=inf;
for(j=1;j<=n;j++)
{
if(!vis[j]&&minz>dis[j])
{
minz=dis[j];
k=j;
}
}
vis[k]=1;
ans=max(ans,minz);
for(j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]>G[k][j])
{
dis[j]=G[k][j];
}
}
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j;
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&G[i][j]);
}
}
prim();
}
return 0;
}
J - Agri-Net http://poj.org/problem?id=1258
Description
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms.
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm.
The distance between any two farms will not exceed 100,000.
Input
Output
Sample Input
4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0
Sample Output
28
#include<stdio.h>
#include<algorithm>
#include<string.h>
int n;
const int inf=0x3f3f3f3f;
int G[105][105],vis[105],dis[105];
void prim()
{
int i,j,k,minz,ans=0;
for(i=1;i<=n;i++)
{
dis[i]=G[1][i];
}
vis[1]=1;
for(i=2;i<=n;i++)
{
k=-1,minz=inf;
for(j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<minz)
{
minz=dis[j];
k=j;
}
}
vis[k]=1;
ans+=minz;
for(j=1;j<=n;j++)
{
if(!vis[j]&&G[k][j]<dis[j])
{
dis[j]=G[k][j];
}
}
}
printf("%d\n",ans);
return ;
}
int main()
{
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&G[i][j]);
}
}
prim();
}
return 0;
}
K - Truck History
http://poj.org/problem?id=1789
Description
Today, ACM is rich enough to pay historians to study its history. One thing historians tried to find out is so called derivation plan -- i.e. how the truck types were derived. They defined the distance of truck types as the number of positions with different letters in truck type codes. They also assumed that each truck type was derived from exactly one other truck type (except for the first truck type which was not derived from any other type). The quality of a derivation plan was then defined as
where the sum goes over all pairs of types in the derivation plan such that t o is the original type and t d the type derived from it and d(t o,t d) is the distance of the types.
Since historians failed, you are to write a program to help them. Given the codes of truck types, your program should find the highest possible quality of a derivation plan.
Input
Output
Sample Input
4 aaaaaaa baaaaaa abaaaaa aabaaaa 0
Sample Output
The highest possible quality is 1/3.
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
int n,dis[2010],vis[2010],G[2010][2010];
char str[2010][10];
int find(int a,int b)
{
int i;
int count=0;
for(i=0;i<10;i++)
{
if(str[a][i]!=str[b][i])
{
count++;
}
}
return count;
}
void prim()
{
int i,j,k,minz,ans=0;
for(i=0;i<n;i++)
{
dis[i]=G[0][i];
}
vis[0]=1;
for(i=1;i<n;i++)
{
k=-1,minz=inf;
for(j=0;j<n;j++)
{
if(!vis[j]&&minz>dis[j])
{
minz=dis[j];
k=j;
}
}
if(k==-1)
{
break;
}
ans+=minz;
vis[k]=1;
for(j=0;j<n;j++)
{
if(!vis[j]&&G[k][j]<dis[j])
{
dis[j]=G[k][j];
}
}
}
printf("The highest possible quality is 1/%d.\n",ans);
}
int main()
{
while(~scanf("%d",&n),n)
{
int i,j;
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
{
scanf("%s",str[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
G[i][j]=G[j][i]=find(i,j);
}
}
prim();
}
return 0;
}
L - 畅通工程续
http://acm.hdu.edu.cn/showproblem.php?pid=1874
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
2 -1
#include<stdio.h>
const int inf=0x3f3f3f3f;
int n,m,G[200][200];
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
{
G[i][j]=0;
}
else
{
G[i][j]=inf;
}
}
}
for(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(G[a][b]>c)
{
G[a][b]=G[b][a]=c;
}
}
int s,f;
scanf("%d%d",&s,&f);
for(int k=0;k<n;k++)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(G[i][j]>G[i][k]+G[k][j])
{
G[i][j]=G[i][k]+G[k][j];
}
}
}
}
if(G[s][f]==inf)
{
printf("-1\n");
}
else
printf("%d\n",G[s][f]);
}
return 0;
}
M - 最短路
http://acm.hdu.edu.cn/showproblem.php?pid=2544
输入保证至少存在1条商店到赛场的路线。
2 1 1 2 3 3 3 1 2 5 2 3 5 3 1 2 0 0
3 2
#include<cstdio>
#include<math.h>
#include<memory.h>
using namespace std;
#define inf 0x3f3f3f3f
int map[105][105],dis[105],vis[105],n,m;
void dij(int a,int b)
{
int i,j,minz,k;
for(i=1;i<=n;i++)
{
dis[i]=map[1][i];
vis[i]=0;
}
vis[a]=1;
for(i=1;i<=n;i++)
{
minz=inf;
for(j=1;j<=n;j++)
{
if(vis[j]==0&&dis[j]<minz)
{
k=j;
minz=dis[j];
}
}
vis[k]=1;
for(j=1;j<=n;j++)
{
if(vis[j]==0&&dis[j]>map[k][j]+dis[k])
{
dis[j]=dis[k]+map[k][j];
}
}
}
printf("%d\n",dis[b]);
}
int main()
{
int i,j,k,a,b,c;
while(~scanf("%d%d",&n,&m),(n||m))
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
memset(map,inf,sizeof(map));
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b]=c;
map[b][a]=c;
}
dij(1,n);
}return 0;
}