湖北中醫藥大學2019暑期練習賽題解(三)

A - Ants POJ - 1852

An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it immediatelly falls off it. When two ants meet they turn back and start walking in opposite directions. We know the original positions of ants on the pole, unfortunately, we do not know the directions in which the ants are walking. Your task is to compute the earliest and the latest possible times needed for all ants to fall off the pole.
Input
The first line of input contains one integer giving the number of cases that follow. The data for each case start with two integer numbers: the length of the pole (in cm) and n, the number of ants residing on the pole. These two numbers are followed by n integers giving the position of each ant on the pole as the distance measured from the left end of the pole, in no particular order. All input integers are not bigger than 1000000 and they are separated by whitespace.
Output
For each case of input, output two numbers separated by a single space. The first number is the earliest possible time when all ants fall off the pole (if the directions of their walks are chosen appropriately) and the second number is the latest possible such time.
Sample Input
2
10 3
2 6 7
214 7
11 12 7 13 176 23 191
Sample Output
4 8
38 207

題目大意

在長爲len的繩子上有n只螞蟻,螞蟻可以左右爬,兩隻螞蟻碰到之後都會掉頭,朝反方向爬,當爬到左右兩端就會落下去。若所有螞蟻掉下去,所需的最長時間和最短時間分別是多少。

解題思路

兩隻螞蟻相碰可以理解爲兩隻螞蟻相互穿過去,因爲兩隻螞蟻本質上沒有區別,兩隻螞蟻共同的狀態並沒有改變。所以最後掉下去的那隻螞蟻,不管有沒有阻攔,都可以看成無阻攔。所以所有螞蟻掉下去的時間最小值就是每隻螞蟻掉下去的時間最小值(這個值就是向左和向右中取出的最小值)中取出時間最大的(時間最長的掉下去說明其他的已經掉下去了)。當所有螞蟻掉下去的時間最大值就是每隻螞蟻掉下去的時間最大值中取出最大的。

注意點:
1.數組比較大,應該開在mian函數之外
2.輸入的量比較大,應該用scanf,用cin會報錯。
3.這裏用萬能頭文件會報錯。

源代碼

#include <stdio.h>
#include <iostream>
#include<algorithm>
using namespace std;
int a[1000005];
int main()
{
    int i,t;
    cin>>t;
    while(t--)
    {
        int len,n;
        cin>>len>>n;
        int mi,ma;
        int min=-1,max=-1;
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            mi=a[i]<(len-a[i])?a[i]:(len-a[i]);
            min=mi>min?mi:min;
            ma=a[i]>(len-a[i])?a[i]:(len-a[i]);
            max=ma>max?ma:max;
        }

        cout<<min<<" "<<max<<endl;

    }

    return 0;
}

B - Lake Counting POJ - 2386

Due to recent rains, water has pooled in various places in Farmer John’s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W’) or dry land (’.’). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors.

Given a diagram of Farmer John’s field, determine how many ponds he has.
Input
* Line 1: Two space-separated integers: N and M

* Lines 2…N+1: M characters per line representing one row of Farmer John’s field. Each character is either ‘W’ or ‘.’. The characters do not have spaces between them.
Output
* Line 1: The number of ponds in Farmer John’s field.
Sample Input
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
Sample Output
3
Hint
OUTPUT DETAILS:

There are three ponds: one in the upper left, one in the lower left,and one along the right side.

題目大意

‘’w‘’表示有水,‘’.‘’代表旱地,一個或者多個w構成一個池塘,多個“w”相連,則認爲他們是一個池塘,相連指的是一個池塘的八個方向之一有另一個池塘,問有多少池塘。

解題思路

這題是一個深搜。以某個w爲起點搜索他的周圍所有的w,當搜過的w置爲已經搜索過,搜索過的不重複搜索。當某個點搜索結束,池塘的數量加1,遍歷所有點,即可得出所有池塘的數量。

源代碼

#include <stdio.h>
#include <iostream>
#include<algorithm>
#include<string.h>
//#include <bits/stdc++.h>
using namespace std;
bool found[105][105];
int n,m;
char a[105][105];
void dfs(int x,int y)
{
    int i,j,k;
    if(found[x][y]==false&&x>=0&&x<n&&y>=0&&y<m)
    {
        found[x][y]=true;

        for(i=-1;i<=1;i++)
        {
            for(j=-1;j<=1;j++)
            {

                if((i+x)>=0&&(i+x)<n&&(j+y)>=0&&(j+y)<m&&a[i+x][j+y]=='W')
                {
                    dfs(i+x,j+y);
                }
            }
        }
    }
}
int main()
{
    int i,j;
    cin>>n>>m;
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            cin>>a[i][j];
        }
    }
    memset(found,false,sizeof(found));
    int count=0;
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            if(found[i][j]==false&&a[i][j]=='W')
            {
                count++;
                dfs(i,j);
            }
        }
    }
    cout<<count<<endl;

    return 0;
}

C - Best Cow Line

FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competition. In this contest every farmer arranges his cows in a line and herds them past the judges.

The contest organizers adopted a new registration scheme this year: simply register the initial letter of every cow in the order they will appear (i.e., If FJ takes Bessie, Sylvia, and Dora in that order he just registers BSD). After the registration phase ends, every group is judged in increasing lexicographic order according to the string of the initials of the cows’ names.

FJ is very busy this year and has to hurry back to his farm, so he wants to be judged as early as possible. He decides to rearrange his cows, who have already lined up, before registering them.

FJ marks a location for a new line of the competing cows. He then proceeds to marshal the cows from the old line to the new one by repeatedly sending either the first or last cow in the (remainder of the) original line to the end of the new line. When he’s finished, FJ takes his cows for registration in this new order.

Given the initial order of his cows, determine the least lexicographic string of initials he can make this way.

Input

  • Line 1: A single integer: N
  • Lines 2…N+1: Line i+1 contains a single initial (‘A’…‘Z’) of the cow in the ith position in the original line

Output
The least lexicographic string he can make. Every line (except perhaps the last one) contains the initials of 80 cows (‘A’…‘Z’) in the new line.

Sample Input
6
A
C
D
B
C
B
Sample Output
ABCBCD

題目大意

從隊列的首尾中取值,得出字典序最小的串。

解題思路

這題用到的是貪心
將隊首和隊尾的值取出來,進行比較,若隊首小就拿出隊首的值,並且輸出,若隊尾小就拿出隊尾的值,並且輸出。
若隊尾與隊首相同,則比較裏面一層字符,若還是相同,繼續向內比較,直到比較出大小。若一直相同,前面的值的位置>=後面的值的位置之後就直接取隊首的值。當隊首的的值的位置>隊尾的值的位置時,說明所有值都已經輸出,循環結束。

源代碼

#include <iostream>
using namespace std;
int main()
{
	int n,i;
	cin>>n;
	char a[2005];
	for(i=0;i<n;i++)
	cin>>a[i];
	int start=0,end=n-1;
	int count=0;
	while(start<=end)
	{
		
		for(i=0;start+i<i+end;i++)
		{
			if(a[i+start]>a[end-i])
			{
				cout<<a[end];
				end--;
				count++;
				if(count%80==0)
					cout<<endl;
				break;
			}	
			else if(a[i+start]<a[end-i])
			{
				cout<<a[start];
				start++;
				count++;
				if(count%80==0)
					cout<<endl;
				break;
			}
			
		}
		if(start+i>=i+end)
		{
			cout<<a[end];
			end--;
			count++;
			if(count%80==0)
				cout<<endl;
		}
		
	}
	return 0;
} 

D - A - Crazy Rows SPOJ - HAROWS

Crazy Rows

You are given an N x N matrix with 0 and 1 values. You can swap any two adjacent rows of the matrix.

Your goal is to have all the 1 values in the matrix below or on the main diagonal. That is, for each X where 1 ≤ X ≤ N, there must be no 1 values in row X that are to the right of column X.

Return the minimum number of row swaps you need to achieve the goal.

Input

The first line of input gives the number of cases, T. T test cases follow.
The first line of each test case has one integer, N. Each of the next N lines contains N characters. Each character is either 0 or 1.

Output

For each test case, output

Case #X: K
where X is the test case number, starting from 1, and K is the minimum number of row swaps needed to have all the 1 values in the matrix below or on the main diagonal.

You are guaranteed that there is a solution for each test case.

Limits

1 ≤ T ≤ 60

1 ≤ N ≤ 8

Input

3
2
10
11
3
001
100
010
4
1110
1100
1100
1000
Output
Case #1: 0
Case #2: 2
Case #3: 4

題目大意

只能交換相鄰行,問最少多少次,可以把所有的1移動到主對角線上,或者主對角線下方。

解題思路

放在第一行的數到放在最後一行,限制越來越小,第一行就只能是00000…,或者10000…,最後一行可以隨意放,。所以應該先從哪一行放在第一行開始考慮,有多行滿足條件的時候就取最近的行,放在第一行的條件滿足之後就繼續往下看第二行,直到最後一行。每行的0和1的位置不重要,重要的是每行最右邊的1的位置,最右邊1的位置可以推出每行可以放的行的範圍。

源代碼

#include <iostream>
#include <algorithm>
using namespace std;
char a[10][10];
int main()
{
	int t;
	cin>>t;
	int kase=0;
	while(t--)
	{
		int n;
		int i,j;
		int aend[10];
		int ans=0;
	
		cin>>n;
		for(i=0;i<n;i++)
		{
			for(j=0;j<n;j++)
			{
				cin>>a[i][j];
			}
		}
		for(i=0;i<n;i++)//找到最右邊的1的位置
		{
			aend[i]=-1;
			for(j=n-1;j>=0;j--)
			{
				if(a[i][j]=='1')
				{
					aend[i]=j;	
					break;		
				}
			}
		}
		for(i=0;i<n;i++)
		{
	 		int pos=-1;//要移動到第i行的行
 		 	for(j=i;j<n;j++)
        	{
	            if(aend[j]<=i)
	            {
	                pos=j;
	                break;
	            }
        	}

        	for(j=pos;j>i;j--)//交換相鄰的行
        	{
        		 
	            swap(aend[j],aend[j-1]);
	            ans++;
       	 	}

		}
		printf("Case #%d: %d\n",++kase,ans);
	}
	return 0;
} 

E - Bribe the Prisoners SPOJ - GCJ1C09C

Problem

In a kingdom there are prison cells (numbered 1 to P) built to form a straight line segment. Cells number i and i+1 are adjacent, and prisoners in adjacent cells are called “neighbours.” A wall with a window separates adjacent cells, and neighbours can communicate through that window.

All prisoners live in peace until a prisoner is released. When that happens, the released prisoner’s neighbours find out, and each communicates this to his other neighbour. That prisoner passes it on to his other neighbour, and so on until they reach a prisoner with no other neighbour (because he is in cell 1, or in cell P, or the other adjacent cell is empty). A prisoner who discovers that another prisoner has been released will angrily break everything in his cell, unless he is bribed with a gold coin. So, after releasing a prisoner in cell A, all prisoners housed on either side of cell A - until cell 1, cell P or an empty cell - need to be bribed.

Assume that each prison cell is initially occupied by exactly one prisoner, and that only one prisoner can be released per day. Given the list of Q prisoners to be released in Q days, find the minimum total number of gold coins needed as bribes if the prisoners may be released in any order.

Note that each bribe only has an effect for one day. If a prisoner who was bribed yesterday hears about another released prisoner today, then he needs to be bribed again.

Input

The first line of input gives the number of cases, N. N test cases follow. Each case consists of 2 lines. The first line is formatted as

P Q

where P is the number of prison cells and Q is the number of prisoners to be released.
This will be followed by a line with Q distinct cell numbers (of the prisoners to be released), space separated, sorted in ascending order.
Output

For each test case, output one line in the format

Case #X: C
where X is the case number, starting from 1, and C is the minimum number of gold coins needed as bribes.
Limits

1 ≤ N ≤ 100
Q ≤ P
Each cell number is between 1 and P, inclusive.

Large dataset

1 ≤ P ≤ 10000
1 ≤ Q ≤ 100

Sample

Input
2
8 1
3
20 3
3 6 14
Output

Case #1: 7
Case #2: 35
Note

In the second sample case, you first release the person in cell 14, then cell 6, then cell 3. The number of gold coins needed is 19 + 12 + 4 = 35. If you instead release the person in cell 6 first, the cost will be 19 + 4 + 13 = 36.

題意

有p個犯人,編號從1到p,現有q個犯人可以被釋放,但是他兩旁的所有犯人看到了覺得很不爽,所以要給1元錢來賄賂他們(請問他在監獄裏到哪去花錢),一直到一個空監獄,要求安排q個犯人釋放的順序,使得總代價最小

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章