POJ - 1251(最小生成树.)、HDU 1043(八数码问题.)、HDU - 2181(dfs.)

Time limit 1000 ms
Memory limit 10000 kB
OS Linux

题目:
The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages. The villages are labeled A through I in the maps above. The map on the right shows the roads that could be maintained most cheaply, for 216 aacms per month. Your task is to write a program that will solve such problems.

Input
The input consists of one to 100 data sets, followed by a final line containing only 0. Each data set starts with a line containing only a number n, which is the number of villages, 1 < n < 27, and the villages are labeled with the first n letters of the alphabet, capitalized. Each data set is completed with n-1 lines that start with village labels in alphabetical order. There is no line for the last village. Each line for a village starts with the village label followed by a number, k, of roads from this village to villages with labels later in the alphabet. If k is greater than 0, the line continues with data for each of the k roads. The data for each road is the village label for the other end of the road followed by the monthly maintenance cost in aacms for the road. Maintenance costs will be positive integers less than 100. All data fields in the row are separated by single blanks. The road network will always allow travel between all the villages. The network will never have more than 75 roads. No village will have more than 15 roads going to other villages (before or after in the alphabet). In the sample input below, the first data set goes with the map above.
Output
The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages. Caution: A brute force solution that examines every possible set of roads will not finish within the one minute time limit.
Sample Input
9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0
Sample Output
216
30

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;

const int N = 30;
const int M = 100;
typedef long long ll;
int n, cnt, fa[N];
struct Node{
    int a, b, len;
}p[M];

void init() {
    cnt = 0;
    for (int i = 0; i <= 27; i++) {
        fa[i] = i;  
    }
}

int cmp(Node x, Node y) {
    return x.len < y.len;
}

int find(int x) {
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

int kruskal() {
    int rec = 0;
    sort(p, p + cnt, cmp);
    double ans = 0;
    for (int i = 0; i < cnt; i++) {
        if (rec == n - 1) break;
        int x = find(p[i].a), y = find(p[i].b);
        if (x != y) {
            fa[x] = y;
            ans += p[i].len;
            rec++;
        }
    }
    return ans;
}

void input() {
    char c[10];
    int a;
    for (int i = 0; i < n - 1; i++) {
        scanf("%s %d", c, &a);
        int u = c[0] - 'A';
        for (int j = 0; j < a; j++)  {
            int b;
            scanf(" %s %d", c, &b);
            int v = c[0] - 'A';
            p[cnt].a = u;
            p[cnt].b = v;
            p[cnt++].len = b; 
        }
    }   
}

int main() {
    while (scanf("%d\n", &n) != EOF) {
        if (!n) break;
        init();
        input();
        printf("%d\n", kruskal());
    }
    return 0;
}

Time limit 5000 ms
Memory limit 32768 kB
Special judge Yes
OS Windows

题目:
The 15-puzzle has been around for over 100 years; even if you don’t know it by that name, you’ve seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let’s call the missing tile ‘x’; the object of the puzzle is to arrange the tiles so that they are ordered as:

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x

where the only legal operation is to exchange ‘x’ with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->

The letters in the previous row indicate which neighbor of the ‘x’ tile is swapped with the ‘x’ tile at each step; legal values are ‘r’,‘l’,‘u’ and ‘d’, for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing ‘x’ tile, of course).

扫描二维码关注公众号,回复: 5111798 查看本文章

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.
Input
You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x’. For example, this puzzle

1 2 3
x 4 6
7 5 8

is described by this list:

1 2 3 x 4 6 7 5 8
Output
You will print to standard output either the word ``unsolvable’’, if the puzzle has no solution, or a string consisting entirely of the letters ‘r’, ‘l’, ‘u’ and ‘d’ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.
Sample Input
2 3 4 1 5 x 7 6 8
Sample Output
ullddrurdllurdruldr

代码:

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int Jc[15]={1,1,2,6,24,120,720,5040,40320,362880,3628800};
int Fx[4]={-3,-1,3,1};
char Sc[4]={'u','l','d','r'};
struct Queue
{
        int num[15];
        int Dad,F,where;
}a[600000];
Queue begin;
bool map[362885];
bool Dd(int n[])   
{
    for(int i=0;i<8;i++)
        if(n[i]!=i+1)
            return false;
    return true;
}
bool Pc(int n[])
{
    int lj=0;
    for(int i=0;i<9;i++) 
        for(int j=i+1;j<9;j++) 
            if(n[j]<n[i])   
                lj+=Jc[8-i];
    if(map[lj]) return true;
    map[lj]=true;
    return false;
}
int main()
{
    int l=0,r=0;
    char c=0;
    begin.Dad=begin.F=-1;
    for(int i=0;i<9;i++)
    {
        scanf("%c",&c);
        if(c-'0'==-16)scanf("%c",&c);
        if(c!='x')begin.num[i]=c-'0';
        else    begin.num[i]=0,begin.where=i;
    }
    //for(int i=0;i<9;i++)
        //printf("%d ",begin.num[i]);
    a[r++]=begin;
    while(l<r)
    {
            Queue first;
            first=a[l];
            for(int i=0;i<4;i++)
            {
                Queue push=first;
                push.Dad=l,push.F=i,push.where=Fx[i]+first.where;
                if(push.where<0||push.where>8||(i%2&&push.where/3!=first.where/3)) continue;
                    swap(push.num[push.where],push.num[first.where]);
                if(Pc(push.num)) continue;
                    a[r++]=push;
                if(Dd(push.num))
                {
                    int x=r-1;
                    vector<int> vec;
                    while(true)
                    {
                    vec.push_back(a[x].F);
                    x=a[x].Dad;
                    if(x==-1) break;
                    }
                    for(int j=vec.size()-2;j>=0;j--)
                    printf("%c",Sc[vec[j]]);
                    printf("\n");
                    return 0;
                }
            }
            l++;
    }
    printf("NO SOLUTION\n");
    return 0;
}

Time limit1000 ms
Memory limit32768 kB
OSWindows

题目:
一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市。
Input
前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出.
Output
输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output
Sample Input
2 5 20
1 3 12
2 4 10
3 5 8
1 4 6
5 7 19
6 8 17
4 7 9
8 10 16
3 9 11
10 12 15
2 11 13
12 14 20
13 15 18
11 14 16
9 15 17
7 16 18
14 17 19
6 18 20
1 13 19
5
0
Sample Output
1: 5 1 2 3 4 8 7 17 18 14 15 16 9 10 11 12 13 20 19 6 5
2: 5 1 2 3 4 8 9 10 11 12 13 20 19 18 14 15 16 17 7 6 5
3: 5 1 2 3 10 9 16 17 18 14 15 11 12 13 20 19 6 7 8 4 5
4: 5 1 2 3 10 11 12 13 20 19 6 7 17 18 14 15 16 9 8 4 5
5: 5 1 2 12 11 10 3 4 8 9 16 15 14 13 20 19 18 17 7 6 5
6: 5 1 2 12 11 15 14 13 20 19 18 17 16 9 10 3 4 8 7 6 5
7: 5 1 2 12 11 15 16 9 10 3 4 8 7 17 18 14 13 20 19 6 5
8: 5 1 2 12 11 15 16 17 18 14 13 20 19 6 7 8 9 10 3 4 5
9: 5 1 2 12 13 20 19 6 7 8 9 16 17 18 14 15 11 10 3 4 5
10: 5 1 2 12 13 20 19 18 14 15 11 10 3 4 8 9 16 17 7 6 5
11: 5 1 20 13 12 2 3 4 8 7 17 16 9 10 11 15 14 18 19 6 5
12: 5 1 20 13 12 2 3 10 11 15 14 18 19 6 7 17 16 9 8 4 5
13: 5 1 20 13 14 15 11 12 2 3 10 9 16 17 18 19 6 7 8 4 5
14: 5 1 20 13 14 15 16 9 10 11 12 2 3 4 8 7 17 18 19 6 5
15: 5 1 20 13 14 15 16 17 18 19 6 7 8 9 10 11 12 2 3 4 5
16: 5 1 20 13 14 18 19 6 7 17 16 15 11 12 2 3 10 9 8 4 5
17: 5 1 20 19 6 7 8 9 10 11 15 16 17 18 14 13 12 2 3 4 5
18: 5 1 20 19 6 7 17 18 14 13 12 2 3 10 11 15 16 9 8 4 5
19: 5 1 20 19 18 14 13 12 2 3 4 8 9 10 11 15 16 17 7 6 5
20: 5 1 20 19 18 17 16 9 10 11 15 14 13 12 2 3 4 8 7 6 5
21: 5 4 3 2 1 20 13 12 11 10 9 8 7 17 16 15 14 18 19 6 5
22: 5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
23: 5 4 3 2 12 11 10 9 8 7 6 19 18 17 16 15 14 13 20 1 5
24: 5 4 3 2 12 13 14 18 17 16 15 11 10 9 8 7 6 19 20 1 5
25: 5 4 3 10 9 8 7 6 19 20 13 14 18 17 16 15 11 12 2 1 5
26: 5 4 3 10 9 8 7 17 16 15 11 12 2 1 20 13 14 18 19 6 5
27: 5 4 3 10 11 12 2 1 20 13 14 15 16 9 8 7 17 18 19 6 5
28: 5 4 3 10 11 15 14 13 12 2 1 20 19 18 17 16 9 8 7 6 5
29: 5 4 3 10 11 15 14 18 17 16 9 8 7 6 19 20 13 12 2 1 5
30: 5 4 3 10 11 15 16 9 8 7 17 18 14 13 12 2 1 20 19 6 5
31: 5 4 8 7 6 19 18 17 16 9 10 3 2 12 11 15 14 13 20 1 5
32: 5 4 8 7 6 19 20 13 12 11 15 14 18 17 16 9 10 3 2 1 5
33: 5 4 8 7 17 16 9 10 3 2 1 20 13 12 11 15 14 18 19 6 5
34: 5 4 8 7 17 18 14 13 12 11 15 16 9 10 3 2 1 20 19 6 5
35: 5 4 8 9 10 3 2 1 20 19 18 14 13 12 11 15 16 17 7 6 5
36: 5 4 8 9 10 3 2 12 11 15 16 17 7 6 19 18 14 13 20 1 5
37: 5 4 8 9 16 15 11 10 3 2 12 13 14 18 17 7 6 19 20 1 5
38: 5 4 8 9 16 15 14 13 12 11 10 3 2 1 20 19 18 17 7 6 5
39: 5 4 8 9 16 15 14 18 17 7 6 19 20 13 12 11 10 3 2 1 5
40: 5 4 8 9 16 17 7 6 19 18 14 15 11 10 3 2 12 13 20 1 5
41: 5 6 7 8 4 3 2 12 13 14 15 11 10 9 16 17 18 19 20 1 5
42: 5 6 7 8 4 3 10 9 16 17 18 19 20 13 14 15 11 12 2 1 5
43: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5
44: 5 6 7 8 9 16 17 18 19 20 1 2 12 13 14 15 11 10 3 4 5
45: 5 6 7 17 16 9 8 4 3 10 11 15 14 18 19 20 13 12 2 1 5
46: 5 6 7 17 16 15 11 10 9 8 4 3 2 12 13 14 18 19 20 1 5
47: 5 6 7 17 16 15 11 12 13 14 18 19 20 1 2 3 10 9 8 4 5
48: 5 6 7 17 16 15 14 18 19 20 13 12 11 10 9 8 4 3 2 1 5
49: 5 6 7 17 18 19 20 1 2 3 10 11 12 13 14 15 16 9 8 4 5
50: 5 6 7 17 18 19 20 13 14 15 16 9 8 4 3 10 11 12 2 1 5
51: 5 6 19 18 14 13 20 1 2 12 11 15 16 17 7 8 9 10 3 4 5
52: 5 6 19 18 14 15 11 10 9 16 17 7 8 4 3 2 12 13 20 1 5
53: 5 6 19 18 14 15 11 12 13 20 1 2 3 10 9 16 17 7 8 4 5
54: 5 6 19 18 14 15 16 17 7 8 9 10 11 12 13 20 1 2 3 4 5
55: 5 6 19 18 17 7 8 4 3 2 12 11 10 9 16 15 14 13 20 1 5
56: 5 6 19 18 17 7 8 9 16 15 14 13 20 1 2 12 11 10 3 4 5
57: 5 6 19 20 1 2 3 10 9 16 15 11 12 13 14 18 17 7 8 4 5
58: 5 6 19 20 1 2 12 13 14 18 17 7 8 9 16 15 11 10 3 4 5
59: 5 6 19 20 13 12 11 10 9 16 15 14 18 17 7 8 4 3 2 1 5
60: 5 6 19 20 13 14 18 17 7 8 4 3 10 9 16 15 11 12 2 1 5

代码:

#include<iostream>
#include<cstring>
using namespace std;
bool map[21][21]; //城市地图 
bool vis[21];    //是否访问过该城市 
int ans[21];     //记录走过的城市 
int num;
int start_city;//起始的出发城市 
 
void dfs(int deepth,int count) //deepth是当前访问的城市,count记录已经访问过多少个城市(一共要访问20个嘛) 
{
	ans[count] = deepth;//将当前城市记录下来 
	if (count==19) //如果已经访问了19个城市就不用访问了,因为第20个城市就是刚开始出发的城市嘛 
	{
		if (map[deepth][cas]==true)//假如第19个城市与第20个(也就是第一个出发点)城市相连 
		{
			cout<<num++<<":  ";
			for (int i=0;i<=19;i++) cout<<ans[i]<<" ";
			cout<<ans[0]<<endl;//打印答案 
		
		}
		
		return ;
	}
	for (int j=1;j<=20;j++)//遍历第一个到第20个城市 
	{
		if (map[deepth][j]==true  && vis[j]==false) //如果第deepth个城市与第j个城市相连,而第j个城市没被访问过 
		{
			vis[j]=true;
			dfs(j,count+1);//下一次递归 
			vis[j]=false;
		}
	}
}
 
 
int main()
{
	int a,b,c;
	memset(map,0,sizeof(map));
	for (int i=1;i<=20;i++)
	{
		cin>>a>>b>>c;
		map[i][a]=true;//表示第i个城市与第a个城市相连 
		map[i][b]=true;//表示第i个城市与第b个城市相连 
		map[i][c]=true;//表示第i个城市与第c个城市相连 
	}
	while (cin>>cas  && cas) 
	{
		num=1;
		memset(vis,0,sizeof(vis));
		memset(ans,0,sizeof(ans));
		vis[start_city] = true;
		dfs(strat_city,0);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43967023/article/details/86684947