冬季集训1.22

冬季集训1.22

A - Brainman

Background
Raymond Babbitt drives his brother Charlie mad. Recently Raymond counted 246 toothpicks spilled all over the floor in an instant just by glancing at them. And he can even count Poker cards. Charlie would love to be able to do cool things like that, too. He wants to beat his brother in a similar task.

Problem
Here’s what Charlie thinks of. Imagine you get a sequence of N numbers. The goal is to move the numbers around so that at the end the sequence is ordered. The only operation allowed is to swap two adjacent numbers. Let us try an example:
Start with: 2 8 0 3
swap (2 8) 8 2 0 3
swap (2 0) 8 0 2 3
swap (2 3) 8 0 3 2
swap (8 0) 0 8 3 2
swap (8 3) 0 3 8 2
swap (8 2) 0 3 2 8
swap (3 2) 0 2 3 8
swap (3 8) 0 2 8 3
swap (8 3) 0 2 3 8
So the sequence (2 8 0 3) can be sorted with nine swaps of adjacent numbers. However, it is even possible to sort it with three such swaps:
Start with: 2 8 0 3
swap (8 0) 2 0 8 3
swap (2 0) 0 2 8 3
swap (8 3) 0 2 3 8
The question is: What is the minimum number of swaps of adjacent numbers to sort a given sequence?Since Charlie does not have Raymond’s mental capabilities, he decides to cheat. Here is where you come into play. He asks you to write a computer program for him that answers the question. Rest assured he will pay a very good prize for it.

Input

The first line contains the number of scenarios.
For every scenario, you are given a line containing first the length N (1 <= N <= 1000) of the sequence,followed by the N elements of the sequence (each element is an integer in [-1000000, 1000000]). All numbers in this line are separated by single blanks.

Output

Start the output for every scenario with a line containing “Scenario #i:”, where i is the number of the scenario starting at 1. Then print a single line containing the minimal number of swaps of adjacent numbers that are necessary to sort the given sequence. Terminate the output for the scenario with a blank line.

Sample Input

4
4 2 8 0 3
10 0 1 2 3 4 5 6 7 8 9
6 -42 23 6 28 -100 65537
5 0 0 0 0 0

Sample Output

Scenario #1:
3

Scenario #2:
0

Scenario #3:
5

Scenario #4:
0

题目大意:对给出序列进行排序,相邻数字的最小互换次数是多少

思路:相邻元素互换满足归并排序,对于序列中的一个数,前面大于它的和后面小于它的数的个数,就是

该数的逆序对数。一个序列的逆序对数就是该序列的所有数的逆序对数的总和。所以题意就是计算一个序列的逆序对数

归并排序是将序列a[l, r]分成两个序列a[l, mid]和a[mid+ 1, r],分别进行归并排序,然后再将这两个有序序列进行归并排序,在归并排序的过程中,设l<=i<=midmid+1<=j<=r,当a[i]<=a[j]时,并不产生逆序对数;而当a[i]> a[j]时,则在有序序列a[l, mid]中,在a[i]后面的数都比a[j]大,将a[j]放在a[i]前,逆序对数就要加上mid-i+1

主要代码:

void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
} 

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
int a[N];
int b[N];
int ans = 0;
void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
} 
int main(){
	int t,n;
	cin>>t;
	for(int i = 1; i<=t;++i){
		cin>>n;
		ans = 0;
		for(int j = 1;j<=n;++j)
		   cin>>a[j];
		mergesort(1,n);
		printf("Scenario #%d:\n",i);
		cout<<ans<<endl;
		cout<<endl; 
	}
	return 0;
}

B - Ultra-QuickSort

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 – the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

题目大意:给出n个整数,由小到大排序在需要的交换相邻的两个数,求最小交换次数

思路与第一题一样,求逆序对

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 5e5+6;
int a[N];
int b[N];
long long ans;
void merge(int p,int m,int q){
	int i=p,j=m+1,k=i;
	while(i<=m&&j<=q){
		if(a[i]<=a[j])
		b[k++] = a[i++];
		else
		b[k++]=a[j++],ans+=m-i+1;
	}
	while(i<=m) b[k++] =a[i++];
	while(j<=q) b[k++] =a[j++];
	for(i = p;i<=q;++i)
	 a[i] = b[i];
}
void mergesort(int p,int q){
	if(p==q) return ;
	else{
		int m = (p+q)/2;
		mergesort(p,m);
		mergesort(m+1,q);
		merge(p,m,q); 
	}
}
int main(){
	int n;
	while(cin>>n&&n){
		ans = 0;
		for(int i = 1;i<=n;++i)
		    cin>>a[i];
		mergesort(1,n);
		cout<<ans<<endl;
	}
	
}

D - Word Amalgamation

In millions of newspapers across the United States there is a word game called Jumble. The object of this game is to solve a riddle, but in order to find the letters that appear in the answer it is necessary to unscramble four words. Your task is to write a program that can unscramble words.

Input

The input contains four parts: 1) a dictionary, which consists of at least one and at most 100 words, one per line; 2) a line containing XXXXXX, which signals the end of the dictionary; 3) one or more scrambled ‘words’ that you must unscramble, each on a line by itself; and 4) another line containing XXXXXX, which signals the end of the file. All words, including both dictionary words and scrambled words, consist only of lowercase English letters and will be at least one and at most six characters long. (Note that the sentinel XXXXXX contains uppercase X’s.) The dictionary is not necessarily in sorted order, but each word in the dictionary is unique.

Output

For each scrambled word in the input, output an alphabetical list of all dictionary words that can be formed by rearranging the letters in the scrambled word. Each word in this list must appear on a line by itself. If the list is empty (because no dictionary words can be formed), output the line “NOT A VALID WORD” instead. In either case, output a line containing six asterisks to signal the end of the list.

Sample Input

tarp
given
score
refund
only
trap
work
earn
course
pepper
part
XXXXXX
resco
nfudre
aptr
sett
oresuc
XXXXXX

Sample Output

score
******
refund
******
part
tarp
trap
******
NOT A VALID WORD
******
course
******

题目大意:首先给出一系列字符串,作为词典,输入遇到******结束,然后再输入一系列需要整理的单词,对每一个需要整理的单词,输出在词典里存在的单词,单词的排列可以不同,如果在词典中找到不知一个单词对应时,要把他们按字典序排列,如果没有找到相对应的单词就输出NOT A VALID WORD,每输出对应的一组单词或NOT A VALID WORD后要 输出****** 。

思路:用str[]字符串数字存储词典,s存储需要整理的单词,s1用于临时接收str的一个字符串;

首先用sort把词典排序,然后输入一个要整理的字符串就对其进行sort排序,同时s1接收词典的单词,也进行sort排序,s1==s,说明词典里面存在这个单词

完整代码:

#include<iostream>
#include<algorithm>
#include<string> 
using namespace std;
const int N = 1e4+6;
string str[N],s,s1;
int cnt,flag;
int main(){
	while(cin>>str[cnt]&&str[cnt]!="XXXXXX"){
		cnt++;
	}
	sort(str,str+cnt);
	while(cin>>s&&s!="XXXXXX"){
		flag = 1;
		sort(s.begin(),s.end());
		for(int i = 0;i<cnt;++i){
			s1 = str[i];
			sort(s1.begin(),s1.end());
			if(s1==s){
				cout<<str[i]<<endl;
				flag = 0;
			}
		}
		if(flag) puts("NOT A VALID WORD");
		puts("******");
	}
	return 0;
}

E排名

今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
考生,并将他们的成绩按降序打印。

Input

测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。

Output

对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
号的升序输出。

Sample Input

4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0

Sample Output

3
CS003 60
CS001 37
CS004 37
0
1
CS000000000000000002 20


        
  

题目大意:统计最高得分

思路:用结构体存储学号和得分,根据解题数和每题得分计算出总分,同时计算过线的人数,根据总分排序

完整代码:

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int N = 1006;
struct data{
	string num;
	int score;
	bool operator <(data x)const{
	    return (score!=x.score)? score>x.score:num<x.num; 
	}
}s[N];
int cot;
int a[N];
int main(){
	int n,m,line;
	while(cin>>n&&n){
	   cin>>m>>line;
	   int sum,cnt;
	   cot = 0;
	   for(int i = 1;i<=m;++i)
	       cin>>a[i];
	    for(int i = 1;i<=n;++i){
	    	cin>>s[i].num>>cnt;
	    	sum = 0;
	    	for(int j = 1;j<=cnt;++j){
	    		int id;
	    		cin>>id;
	    		sum+=a[id];
			}
			s[i].score = sum;
			if(sum>=line) cot++;
		}
		cout<<cot<<endl;
		sort(s+1,s+1+n);
		for(int i = 1;i<=cot;++i){
			cout<<s[i].num<<" "<<s[i].score<<endl;
		}
	}

	return 0;
} 

F - Election Time

The cows are having their first election after overthrowing the tyrannical Farmer John, and Bessie is one of N cows (1 ≤ N ≤ 50,000) running for President. Before the election actually happens, however, Bessie wants to determine who has the best chance of winning.

The election consists of two rounds. In the first round, the K cows (1 ≤ KN) cows with the most votes advance to the second round. In the second round, the cow with the most votes becomes President.

Given that cow i expects to get Ai votes (1 ≤ Ai ≤ 1,000,000,000) in the first round and Bi votes (1 ≤ Bi ≤ 1,000,000,000) in the second round (if he or she makes it), determine which cow is expected to win the election. Happily for you, no vote count appears twice in the Ai list; likewise, no vote count appears twice in the Bi list.

Input

* Line 1: Two space-separated integers: N and K
* Lines 2…N+1: Line i+1 contains two space-separated integers: Ai and Bi

Output

* Line 1: The index of the cow that is expected to win the election.

Sample Input

5 3
3 10
9 2
5 6
8 4
6 5

Sample Output

5

题目大意:奶牛们竞选总统,有两轮投票,第一轮投票的前k头牛可以进行第二轮投票,最后输出最有可能竞选成功的奶牛的编号(得票数最多)

思路:结构体存储各奶牛两轮得票,和编号,第一次按a轮得票数降序排序,第二轮对第一轮前k头奶牛得票数排序最后输出奶牛编号

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 5e4+6;
struct data{
	ll a,b;
	int id;
}d[N];
int n,k;
bool cmpa(data p,data q){
	return p.a>q.a;
}
bool cmpb(data p,data q){
	return p.b>q.b;
}
int main(){
	cin>>n>>k;
	for(int i = 1;i<=n;++i){
		cin>>d[i].a>>d[i].b;
		d[i].id = i;
	}
	sort(d+1,d+n+1,cmpa);
	sort(d+1,d+k+1,cmpb);
	printf("%d\n",d[1].id);
	return 0;
}

G - Holiday Hotel

Mr. and Mrs. Smith are going to the seaside for their holiday. Before they start off, they need to choose a hotel. They got a list of hotels from the Internet, and want to choose some candidate hotels which are cheap and close to the seashore. A candidate hotel M meets two requirements:

  1. Any hotel which is closer to the seashore than M will be more expensive than M.
  2. Any hotel which is cheaper than M will be farther away from the seashore than M.

Input

There are several test cases. The first line of each test case is an integer N (1 <= N <= 10000), which is the number of hotels. Each of the following N lines describes a hotel, containing two integers D and C (1 <= D, C <= 10000). D means the distance from the hotel to the seashore, and C means the cost of staying in the hotel. You can assume that there are no two hotels with the same D and C. A test case with N = 0 ends the input, and should not be processed.

Output

For each test case, you should output one line containing an integer, which is the number of all the candidate hotels.

Sample Input

5
300 100
100 300
400 200
200 400
100 500
0

Sample Output

2

题目大意:

Smith夫妇要去海边渡假,在他们出发前,他们要选择一家宾馆。他们从互联网上获得了一份宾馆的列表,要从中选择一些既便宜又离海滩近的侯选宾馆。侯选宾馆M要满足两个需求:

• 1. 离海滩比M近的宾馆要比M贵。

• 2. 比M便宜的宾馆离海滩比M远。

输出所有可以满足条件的候选宾馆的数目

思路:结构体存储每家宾馆的距离,价格,有两种排序方法,1.以价格作为第一关键字排序,之后找最近的宾馆,2.以距离作为第一关键字排序,找最便宜的价格

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
struct data{
	int dis,cs;
	bool operator<(data x){
		return cs==x.cs? dis<x.dis:cs<x.cs;
	}
}d[N];
int n;
int main(){
	while(cin>>n&&n){
		int ans = 0;
		for(int i = 1; i<=n;++i){
			cin>>d[i].dis>>d[i].cs;
		}
		sort(d+1,d+n+1);
		int minx = 99999999;
		for(int i = 1;i<=n;++i){
			if(d[i].dis<minx){
				minx = d[i].dis;
				ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

构体存储每家宾馆的距离,价格,有两种排序方法,1.以价格作为第一关键字排序,之后找最近的宾馆,2.以距离作为第一关键字排序,找最便宜的价格

完整代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e4+6;
struct data{
	int dis,cs;
	bool operator<(data x){
		return cs==x.cs? dis<x.dis:cs<x.cs;
	}
}d[N];
int n;
int main(){
	while(cin>>n&&n){
		int ans = 0;
		for(int i = 1; i<=n;++i){
			cin>>d[i].dis>>d[i].cs;
		}
		sort(d+1,d+n+1);
		int minx = 99999999;
		for(int i = 1;i<=n;++i){
			if(d[i].dis<minx){
				minx = d[i].dis;
				ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45719435/article/details/112991584