tzcacm去年训练的好题的AC代码及题解

 

A - Tree

 UVA - 548

You are to determine the value of the leaf node in a given binary tree that is the terminal node of a
path of least value from the root of the binary tree to any leaf. The value of a path is the sum of values
of nodes along that path.
Input
The input file will contain a description of the binary tree given as the inorder and postorder traversal
sequences of that tree. Your program will read two line (until end of file) from the input file. The first
line will contain the sequence of values associated with an inorder traversal of the tree and the second
line will contain the sequence of values associated with a postorder traversal of the tree. All values
will be different, greater than zero and less than 10000. You may assume that no binary tree will have
more than 10000 nodes or less than 1 node.
Output
For each tree description you should output the value of the leaf node of a path of least value. In the
case of multiple paths of least value you should pick the one with the least value on the terminal node.
Sample Input
3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255
Sample Output
1
3
255

给你一棵二叉树的中序和后序遍历,那么你的这棵树就是确定了的,让你找到最小的一半枝

其实就是每一层深度都统计下,完全可以弄进这个二叉树

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int in[N],post[N],ans,mi;
void solve(int l,int r,int f,int s)
{
    if(l==r)return;
    if(r-l<=1)
    {
        if(in[l]+s<mi)mi=in[l]+s,ans=in[l];
        return ;
    }
    for(int i=l;i<r;i++)
        if(in[i]==post[f])solve(i+1,r,f-1,s+post[f]),solve(l,i,f+i-r,s+post[f]);
}
int main()
{
    ios::sync_with_stdio(false);
    string s,c;
    while(getline(cin,s))
    {
        getline(cin,c);
        mi=1<<30;
        stringstream ss(s),sc(c);
        int n=0;
        while(ss>>in[n])sc>>post[n++];
        solve(0,n,n-1,0);
        cout<<ans<<"\n";
    }
    return 0;
}

只有给你前序和后序是没有唯一的中序遍历的,是2^n,因为可以是左子树,也可以是右子树

#include <stdio.h>
#include <string.h>
int pre[10005];
int post[10005];
int cc;
void calc(int a1,int b1,int a2,int b2)
{
    int i;
    if(a1>=b1)  return;
    for(i=a2; i<=b2-1; i++)
    {
        if(pre[a1+1] == post[i])  break;
    }
    if(i == b2-1)  cc++;
    calc(a1+1,a1+1+(i-a2),a2,i);
    calc(a1+1+(i-a2)+1,b1,i+1,b2-1);
}
int a[100000];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
        scanf("%d",&pre[i]);
    for(int i=0; i<n; i++)
        scanf("%d",&post[i]);
    cc=0;
    calc(0,n-1,0,n-1);
    n=cc;
    int sum=1,i,k;
    for(i=1; i<100000; i++)
        a[i]=0;
    a[0]=1;
    for(k=1; k<=n; k++)
    {
        for(i=0; i<sum; i++)
            a[i]=a[i]*2;
        for(i=0; i<sum; i++)
            if(a[i]>=10)
            {
                a[i+1]=a[i+1]+a[i]/10;
                if(i+1==sum)sum++;
                a[i]=a[i]%10;
            }
    }
    for(i=sum-1; i>=0; i--)
        printf("%d",a[i]);
    printf("\n");
return 0;
}

B - Til the Cows Come Home

 POJ - 2387 

Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessie needs her beauty sleep, so she wants to get back as quickly as possible. 

Farmer John's field has N (2 <= N <= 1000) landmarks in it, uniquely numbered 1..N. Landmark 1 is the barn; the apple tree grove in which Bessie stands all day is landmark N. Cows travel in the field using T (1 <= T <= 2000) bidirectional cow-trails of various lengths between the landmarks. Bessie is not confident of her navigation ability, so she always stays on a trail from its start to its end once she starts it. 

Given the trails between the landmarks, determine the minimum distance Bessie must walk to get back to the barn. It is guaranteed that some such route exists.

Input

* Line 1: Two integers: T and N 

* Lines 2..T+1: Each line describes a trail as three space-separated integers. The first two integers are the landmarks between which the trail travels. The third integer is the length of the trail, range 1..100.

Output

* Line 1: A single integer, the minimum distance that Bessie must travel to get from landmark N to landmark 1.

Sample Input

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

Sample Output

90

Hint

INPUT DETAILS: 

There are five landmarks. 

OUTPUT DETAILS: 

Bessie can get home by following trails 4, 3, 2, and 1.
 

 用我常用的垃圾模板,只要不卡直接这个模板稳过啊

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
const int N=1005,INF=0x3f3f3f3f;
vector<pair<int,int> >G[N];
priority_queue<int>Q;
int dis[N];
int main()
{
    int n,m;
    cin>>m>>n;
    for(int i=0,u,v,w;i<m;i++)
        cin>>u>>v>>w,G[u].push_back(make_pair(w,v)),G[v].push_back(make_pair(w,u));
    vector<pair<int,int> >::iterator it;
    fill(dis,dis+n+1,INF);
    dis[1]=0,Q.push(1);
    while(!Q.empty())
    {
        int u=Q.top();
        Q.pop();
        for(it=G[u].begin();it!=G[u].end();it++)
            if(dis[u]+it->first<dis[it->second])dis[it->second]=dis[u]+it->first,Q.push(it->second);
    }
    cout<<dis[n];
}

C - Frogger

 POJ - 2253 

Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists' sunscreen, he wants to avoid swimming and instead reach her by jumping. 
Unfortunately Fiona's stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps. 
To execute a given sequence of jumps, a frog's jump range obviously must be at least as long as the longest jump occuring in the sequence. 
The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones. 

You are given the coordinates of Freddy's stone, Fiona's stone and all other stones in the lake. Your job is to compute the frog distance between Freddy's and Fiona's stone. 

Input

The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy's stone, stone #2 is Fiona's stone, the other n-2 stones are unoccupied. There's a blank line following each test case. Input is terminated by a value of zero (0) for n.

Output

For each test case, print a line saying "Scenario #x" and a line saying "Frog Distance = y" where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

Sample Input

2
0 0
3 4

3
17 4
19 4
18 5

0

Sample Output

Scenario #1
Frog Distance = 5.000

Scenario #2
Frog Distance = 1.414

FLOYD最短路

#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define fi first
#define se second
const int MAXN=210;
pair<int,int>p[MAXN];
double dis(pair<int,int>p1,pair<int,int>p2) {
    return (p1.fi-p2.fi)*(p1.fi-p2.fi)+(p2.se-p1.se)*(p2.se-p1.se);
}
int dist[MAXN][MAXN];
int main() {
    int n,cas=1;
    while(~scanf("%d",&n)) {
        if(!n)break;
        for(int i=0; i<n; i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            p[i]=make_pair(x,y);
        }
        for(int i=0; i<n; i++)
            for(int j=i; j<n; j++) {
                dist[j][i]=dist[i][j]=dis(p[i],p[j]);
            }
        for(int k=0; k<n; k++)
            for(int i=0; i<n; i++)
                for(int j=0; j<n; j++)
                    if(dist[i][j]>max(dist[i][k],dist[k][j]))
                        dist[i][j]=max(dist[i][k],dist[k][j]);
        printf("Scenario #%d\n",cas++);
        printf("Frog Distance = %.3f\n\n",sqrt(dist[0][1]*1.0));
    }
    return 0;
}

D - 0 or 1

 HDU - 4370 

Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij(1<=i,j<=n),which is 0 or 1. 

Besides,X ij meets the following conditions: 

1.X 12+X 13+...X 1n=1 
2.X 1n+X 2n+...X n-1n=1 
3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n). 

For example, if n=4,we can get the following equality: 

12+X 13+X 14=1 
14+X 24+X 34=1 
12+X 22+X 32+X 42=X 21+X 22+X 23+X 24 
13+X 23+X 33+X 43=X 31+X 32+X 33+X 34 

Now ,we want to know the minimum of ∑C ij*X ij(1<=i,j<=n) you can get. 
Hint

For sample, X 12=X 24=1,all other X ij is 0. 

InputThe input consists of multiple test cases (less than 35 case). 
For each test case ,the first line contains one integer n (1<n<=300). 
The next n lines, for each lines, each of which contains n integers, illustrating the matrix C, The j-th integer on i-th line is C ij(0<=C ij<=100000).OutputFor each case, output the minimum of ∑C ij*X ij you can get. 
Sample Input

4
1 2 4 10
2 0 1 1
2 2 0 5
6 3 1 2

Sample Output

3

题目也不容易让你想到最短路,最后其实那个式子就是求一下1到n的最短路,或者结点1的最小闭环(不包括自环)+节点n的最小闭环(不包括自环)的值

那个模板处理不了自环的,但是其实就是1-a,然后a-1,求一下正着的最短路还有反着的最短路就好了吧

#include <stdio.h>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=310;
int n,g[N][N],dis[N],dis1[N];
int dij(int s)
{
    fill(dis,dis+N,INF);
    priority_queue<int> pq;
    dis[s]=0,pq.push(s);
    while(!pq.empty())
    {
        int u=pq.top();
        pq.pop();
        for(int i=1;i<=n;i++)
        if(dis[i]>dis[u]+g[u][i])dis[i]=dis[u]+g[u][i],pq.push(i);
    }
}
int dij1(int s)
{
    fill(dis1,dis1+N,INF);
    priority_queue<int> pq;
    dis1[s]=0,pq.push(s);
    while(!pq.empty())
    {
        int u=pq.top();
        pq.pop();
        for(int i=1;i<=n;i++)
            if(dis1[i]>dis1[u]+g[i][u])dis1[i]=dis1[u]+g[i][u],pq.push(i);
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
                scanf("%d",&g[i][j]);
            g[i][i]=INF;
        }
        dij(1),dij1(1);
        int mi1=INF,mi=dis[n],mi2=INF;
        for(int i=2;i<=n;i++)
            mi1=min(dis[i]+dis1[i],mi1);
        dij(n),dij1(n);
        for(int i=1;i<n;i++)
            mi2=min(dis[i]+dis1[i],mi2);
        printf("%d\n",min(mi,mi1+mi2));
    }
    return 0;
}

还有一份逆天点的代码,dij经典写法,找到没有访问的点的最小的边

#include <stdio.h>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=310;
int n,g[N][N],dis[N];
bool did[N];
int dij(int s,int t)
{
    for(int i=1; i<=n; i++)
    {
        if(i!=s)dis[i]=g[s][i];
        else dis[i]=INF;
        did[i]=0;
    }
    int c=0;
    while(c<n)
    {
        int mi,m=INF;
        for(int i=1; i<=n; i++)
            if(!did[i]&&dis[i]<m)
            {
                m=dis[i];
                mi=i;
            }
        did[mi]=1;
        for(int i=1; i<=n; i++)
            if(!did[i]&&dis[i]>dis[mi]+g[mi][i])
            {
                dis[i]=dis[mi]+g[mi][i];
            }
        c++;
    }
    return dis[t];
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&g[i][j]);
            }
        printf("%d\n",min(dij(1,n),dij(1,1)+dij(n,n)));
    }
    return 0;

E - Layout

 POJ - 3169 

Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbered, and since they can be rather pushy, it is possible that two or more cows can line up at exactly the same location (that is, if we think of each cow as being located at some coordinate on a number line, then it is possible for two or more cows to share the same coordinate). 

Some cows like each other and want to be within a certain distance of each other in line. Some really dislike each other and want to be separated by at least a certain distance. A list of ML (1 <= ML <= 10,000) constraints describes which cows like each other and the maximum distance by which they may be separated; a subsequent list of MD constraints (1 <= MD <= 10,000) tells which cows dislike each other and the minimum distance by which they must be separated. 

Your job is to compute, if possible, the maximum possible distance between cow 1 and cow N that satisfies the distance constraints.

Input

Line 1: Three space-separated integers: N, ML, and MD. 

Lines 2..ML+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at most D (1 <= D <= 1,000,000) apart.

Lines ML+2..ML+MD+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at least D (1 <= D <= 1,000,000) apart.

Output

Line 1: A single integer. If no line-up is possible, output -1. If cows 1 and N can be arbitrarily far apart, output -2. Otherwise output the greatest possible distance between cows 1 and N.

Sample Input

4 2 1
1 3 10
2 4 20
2 3 3

Sample Output

27

Hint

Explanation of the sample: 

There are 4 cows. Cows #1 and #3 must be no more than 10 units apart, cows #2 and #4 must be no more than 20 units apart, and cows #2 and #3 dislike each other and must be no fewer than 3 units apart. 

The best layout, in terms of coordinates on a number line, is to put cow #1 at 0, cow #2 at 7, cow #3 at 10, and cow #4 at 27.
差分约束,这个还是很难的

 

 

 

Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feeling giddy. Now, try to help Xiao Bao.

InputThere are several test cases. For each test case, the first line of input contains two positive integer n, k. Then n lines follow. If Xiao Ming choose to write down a number, there will be an " I" followed by a number that Xiao Ming will write down. If Xiao Ming choose to ask Xiao Bao, there will be a "Q", then you need to output the kth great number. 
OutputThe output consists of one integer representing the largest number of islands that all lie on one line. 
Sample Input

8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q

Sample Output

1
2
3


        
 

Hint

Xiao  Ming  won't  ask  Xiao  Bao  the  kth  great  number  when  the  number  of  the  written number is smaller than k. (1=<k<=n<=1000000).

题目还是挺简单易懂的,就是有insert还有query操作
但是可能是重复的,所以multiset
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main()
{
    int n,k,i;
    while(cin>>n>>k)
    {
        multiset<int>v;
        while(n--)
        {
            string s;
            cin>>s;
            if(s=="I")
            {
                int x;
                cin>>x;
                v.insert(x);
                if(v.size()>k)v.erase(v.begin());
            }
            else if(s=="Q")
            {
                cout<<*v.begin()<<endl;
            }
        }
    }
    return 0;
}

 

posted @ 2018-03-29 15:20  暴力都不会的蒟蒻  阅读(371)  评论(0编辑  收藏  举报