HHTC_学校集训编程题目(1)(C++)

学校集训编程题目(1)(C++)


为了参加省赛,也为了提高编程能力,学校要求开始进行集训了
记录一下这几道题目~

Fire Net

Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall.

A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening.

Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets.

The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through.

The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways.
在这里插入图片描述

Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration.

Input

The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.’ indicating an open space and an uppercase ‘X’ indicating a wall. There are no spaces in the input file.

Output

For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration.

Sample Input

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

Sample Output

5
1
5
2
4

就是采用遍历的思想,遍历每一个点,然后再看这个点能不能放

AC代码:

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int ans,n;
char s[5][5];

bool judge(int x,int y){
    for(int i=x-1;i>=0;i--){
        if(s[i][y] == '0')
            return false;
        if(s[i][y] == 'X')
            break;
    }
    for(int i=y-1;i>=0;i--){
        if(s[x][i] == '0')
            return false;
        if(s[x][i] == 'X')
            break;
    }
    return true;
}

void dfs(int k, int num){
    if(k == n*n){
        if(num > ans)
            ans = num;
        return ;
    }
    int x = k / n;
    int y = k % n;
    if(s[x][y] == '.' && judge(x,y)){
        s[x][y] = '0';
        dfs(k + 1, num + 1);
        s[x][y] = '.';
    }
    dfs(k + 1, num);
}

int main()
{
    while(cin>>n){
        if(n == 0)
            break;
        ans = 0;
        for(int i = 0; i < n; i++){
            getchar();
            for(int j = 0; j < n; j++){
                cin>>s[i][j];
            }
        }
        dfs(0,0);
        cout<<ans<<endl;
    }
    return 0;
}

Wooden Sticks

There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:

(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will

need no setup time for a stick of length l’ and weight w’ if l<=l’ and w<=w’. Otherwise, it will need 1 minute for setup.

You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, …, ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.

Output

The output should contain the minimum setup time in minutes, one per line.

Sample Input

3 
5 
4 9 5 2 2 1 3 5 1 4 
3 
2 2 1 1 2 2 
3 
1 3 2 2 3 1

Sample Output

2
1
3

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

struct node{
    int x,y;
}date[5005];

bool cmp(node a,node b){
    if(a.x == b.x)
        return a.y < b.y;
    return a.x < b.x;
}

int vis[5005];

int main(){
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        int num = 0,w;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++){
            cin>>date[i].x>>date[i].y;
        }
        sort(date,date+n,cmp);
        for(int i=0;i<n;i++){
            w = date[i].y;
            if(vis[i] == 0){
                for(int j = i+1;j<n;j++){
                    if(vis[j] == 0 && date[i].x <= date[j].x && w <= date[j].y){
                        vis[j] = 1;
                        w = date[j].y;
                    }
                }
                num++;
                vis[i] = 1;
            }
        }
        if(vis[n-1] == 0)
            num++;
        cout<<num<<endl;
    }
    return 0;
}

Tian Ji – The Horse Racing

Here is a famous story in Chinese history.

“That was about 2300 years ago. General Tian Ji was a high official in
the country Qi. He likes to play horse racing with the king and
others.”

“Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser.”

“Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian’s. As a result, each time the king takes six hundred silver dollars from Tian.”

“Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match.”

“It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king’s regular, and his super beat the king’s plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?”
在这里插入图片描述
Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian’s horses on one side, and the king’s horses on the other. Whenever one of Tian’s horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching…

However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses — a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.

In this problem, you are asked to write a program to solve this special case of matching problem.

Input

The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.
Output
For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.

Sample Input

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0

Sample Output

200
0
0

思路:

  1. 如果田忌的最快马快于齐王的最快马,则两者比。(因为若是田忌的别的马很可能就赢不了了,所以两者比)

  2. 如果田忌的最快马慢于齐王的最快马,则用田忌的最慢马和齐王的最快马比。(由于所有的马都赢不了齐王的最快马,所以用损失最小的,拿最慢的和他比)

  3. 若相等,则比较田忌的最慢马和齐王的最慢马
    3.1、若田忌最慢马快于齐王最慢马,两者比。(田忌的最慢马既然能赢一个就赢呗,而且齐王的最慢马肯定也得有个和他比,所以选最小的比他快的。)
    3.2、其他,则拿田忌的最慢马和齐王的最快马比。(反正所有的马都比田忌的最慢马快了,所以这匹马必输,选贡献最大的,干掉齐王的最快马)

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int tj[1005],king[1005];

int main(){
    int n;
    while(cin>>n && n != 0){
        int num = 0;
        int tj_min = 0,tj_max = n-1;
        int king_min = 0,king_max = n-1;
        memset(tj,0,sizeof(tj));
        memset(king,0,sizeof(king));
        for(int i=0;i<n;i++)
            cin>>tj[i];
        for(int i=0;i<n;i++)
            cin>>king[i];
        sort(tj,tj+n);
        sort(king,king+n);
        while(n--){
            if(tj[tj_max] > king[king_max]){
                num++;
                tj_max--;
                king_max--;
            }else if(tj[tj_max] < king[king_max]){
                num--;
                tj_min++;
                king_max--;
            }else{
                if(tj[tj_min] > king[king_min]){
                    num++;
                    tj_min++;
                    king_min++;
                }else{
                    if(tj[tj_min] < king[king_max])
                        num--;
                    tj_min++;
                    king_max--;
                }
            }
        }
        cout<<num*200<<endl;
    }
    return 0;
}

Filthy Rich

They say that in Phrygia, the streets are paved with gold. You’re currently on vacation in Phrygia, and to your astonishment you discover that this is to be taken literally: small heaps of gold are distributed throughout the city. On a certain day, the Phrygians even allow all the tourists to collect as much gold as they can in a limited rectangular area. As it happens, this day is tomorrow, and you decide to become filthy rich on this day. All the other tourists decided the same however, so it’s going to get crowded. Thus, you only have one chance to cross the field. What is the best way to do so?

Given a rectangular map and amounts of gold on every field, determine the maximum amount of gold you can collect when starting in the upper left corner of the map and moving to the adjacent field in the east, south, or south-east in each step, until you end up in the lower right corner.

Input

The input starts with a line containing a single integer, the number of test cases.
Each test case starts with a line, containing the two integers r and c, separated by a space (1 <= r, c <= 1000). This line is followed by r rows, each containing c many integers, separated by a space. These integers tell you how much gold is on each field. The amount of gold never negative.
The maximum amount of gold will always fit in an int.

Output

For each test case, write a line containing “Scenario #i:”, where i is
the number of the test case, followed by a line containing the maximum
amount of gold you can collect in this test case. Finish each test
case with an empty line.

Sample Input

1
3 4
1 10 8 8
0 0 1 8
0 27 0 4

Sample Output

Scenario #1:
42

思路:
一开始觉得可以使用dfs直接搜索整个数组,然后发现肯定会超时
因为数组比较大,所以采用动归,其实也不知道算不算动归
就是直接比较左边和上边两个数,找最大的,然后直接加上
遍历一遍数组即可~
看不懂因为,导致表达错误wrong了好几次,就是空行的问题~~

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int dp[1005][1005];

int main(){
    int T;
    cin>>T;
    for(int k = 1; k <= T; k++){
        int n,m;
        cin>>n>>m;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>dp[i][j];
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(dp[i-1][j] > dp[i][j-1]){
                    dp[i][j] += dp[i-1][j];
                }else{
                    dp[i][j] += dp[i][j-1];
                }
            }
        }
        cout<<"Scenario #"<<k<<":"<<endl;
        cout<<dp[n][m]<<endl<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值