鸽了好几周der周记(习题+感悟)

(一)UCF Local Programming Contest 2018

A - Historical TV Remote Control

题目描述

As Dr. Orooji is getting older, he is becoming more attached to older items and has difficultyletting go of them (he claims they have historical value). For example, he still has the first tablehe got for the programming team! The situation is the same at home, e.g., there is a broken TVremote control but Dr. O still uses it, because he considers it an old item with historical value!
The Problem:
The old remote control has 12 buttons: digits 0-9, channel down, and channel up. There are noother buttons on the remote control. Some digits on the remote don’t work but channel up/downalways works. So, to get to a particular channel, Dr. O sometimes has to use the channel up/down.For example, let’s assume digits 0 and 5 on the remote don’t work: If Dr. O wants to watch channel 102, he would select 99 and then “channel up” 3 times.
If he wants to watch channel 597, he would select 611 and then “channel down” 14 times.
Given the digits that do not work and a target channel, determine how many times Dr. O needs to hit channel up or down. Dr. O, of course, wants to exert the least energy, hence he wants to hit the channel up/down the minimum number of times. Assume that Dr. O will enter a channel between 0 and 999 (inclusive) to start and that channel down has no effect at 0 and channel up has no effect at 999.

Input

The first input line contains an integer, n (1 ≤ n ≤ 9), indicating how many digits on the remote donot work. These broken digits are listed (in increasing order) on the same input line. The secondinput line provides the target channel (an integer between 1 and 999, inclusive).

Output

The output consists of a single integer, indicating how many times Dr. O needs to hit channelup/down. Note that, since one or more digits work, it is always possible to reach the target channel.

Sample Input

样例输入
3 0 8 9
35
样例输入
4 1 2 5 9
250

Sample Output

样例输出
0
样例输出
50

理解

题目不难就是暴力找,wa好几发错在没判0

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
int vis[10];
int check(int a){
	if(a < 0 || a > 999) return 0;
	if(a == 0 && vis[0] == 1) return 0;
	while(a){
		if(vis[a%10]==1) return 0;
		a /= 10;
	}
	return 1;
}
int main(){
	memset(vis,0,sizeof(vis));
	int n;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		int x;
		scanf("%d",&x);
		vis[x] = 1;
	}
	int y;
	scanf("%d",&y);
	int cnt = 0;
	while(1){
		if(check(y-cnt) || check(y+cnt)){
			break;
		}
		else cnt++;
	}
	cout << cnt << endl;
    return 0;
}

B - First Last Sorting

题目描述

Arup has just created a data structure that makes the two following list transformations in constant O(1) time:
a. Take any element in the list and move it to the front.
b. Take any element in the list and move it to the back.
You’ve realized that sorting speed can be improved using these transformations. For example, consider the input list:
8, 3, 6, 7, 4, 1, 5, 2
We can do the following sequence of transformations to sort this list:
8, 3, 7, 4, 1, 5, 2, 6 (move 6 to end)
8, 3, 4, 1, 5, 2, 6, 7 (move 7 to end)
2, 8, 3, 4, 1, 5, 6, 7 (move 2 to front)
1, 2, 8, 3, 4, 5, 6, 7 (move 1 to front)
1, 2, 3, 4, 5, 6, 7, 8 (move 8 to end)
You are now curious. Given an input array of distinct values, what is the fewest number of these first/last operations necessary to sort the array?
The Problem:
Given an initial permutation of the integers 1, 2, …, n, determine the fewest number of first/last operations necessary to get the list of values sorted in increasing order.

Input

The first line of input will contain a single positive integer, n (n ≤ 1e5), representing the number of values to be sorted. The next n lines contain one integer each. All of these integers will be distinct values in between 1 and n (inclusive), representing the original order of the data to sort for the input case.

Output

On a line by itself, output the fewest number of first/last operations necessary to sort the input list.
输出时每行末尾的多余空格,不影响答案正确性

Sample Input

样例输入1
8
8
3
6
7
4
1
5
2
样例输入2
5
1
2
5
3
4

Sample Output

样例输出1
5
样例输出2
1

理解

这题起先想的太复杂了
后来发现她要求按1递增所以直接记录
最长上升1的子序列长度就好

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
map<int,int> mp;

int main(){
	int n;
	scanf("%d",&n);
	int ans = 0;
	for(int i = 1;i <= n;i++){
		int x;
		scanf("%d",&x);
		mp[x] = mp[x-1]+1;
		ans = max(mp[x],ans);
	}
	cout << n - ans << endl;
    return 0;
}

(二)UCF Local Programming Contest 2016

A - Dot the i’s and Cross the T’s

题目描述

Mr. T, known for his hair cut and the phrase “you fool” in the old TV series “The A Team”, has decided to try out for the UCF Programming Team. Considering the many talented students at UCF, Mr. T’s best chance is to become great at geometry. So, he sought help from Euclid, one of the Fathers of Geometry. Considering the teacher and the student, the obvious place to start is with the letter T!
Consider the picture of the letter T to the right. We define four points A, M, B, and C form a T if three conditions holds:

  1. M is the midpoint of AB

  2. CM = AB, i.e., CM is the same length as AB

  3. The angles AMC and BMC are 90 degrees.
    在这里插入图片描述
    The Problem:
    Given a set of points, you are to determine how many groups of four points form a T based on the above definition.

Input

The first input line contains an integer, n (1 ≤ n ≤ 100), indicating the number of test cases to process. Each test case starts with an integer, p (4 ≤ p ≤ 50), indicating the number of points. Each of the following p input lines provides two real numbers (each between -1000 and 1000, inclusive), indicating (respectively) the x and y coordinates for a point. Assume all points are distinct.

Output

For each set of points, print “Set #n: m”, where n indicates the set number starting with 1 and m indicates how many groups of four points form a T. Two groups of four points are considered different if they differ in at least one point. Leave a blank line after the output for each set.
Note/Hint: This problem deals with floating-point numbers and one must be careful aboutchecking for equality of two values. Assume two values are equal if they differ by 1e-6.png or less.

Sample Input

2
5
5.0 2.0
3.0 6.0
5.0 6.0
7.0 6.0
5.0 10.0
4
-3.0 6.0
0.0 6.0
3.0 6.0
0.0 12.0

Sample Output

Set #1: 2

Set #2: 1

理解

这题莫名其妙wa了好多发,因为我用向量判垂直
后来改用勾股定理就没问题了(一头雾水)
然后还有判断满足少了一些细节条件

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
double x[57],y[57];

double dis(int i,int j){
	return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
int main(){ 
	int cas;
	scanf("%d",&cas);
	for(int e = 1;e <= cas;e++){
		int ans = 0;
		int n;
		scanf("%d",&n);
		for(int i = 1;i <= n;i++){
			scanf("%lf %lf",&x[i],&y[i]);
		}
		for(int i = 1;i <= n;i++){ //A
			for(int j = 1;j <= n;j++){ //B
				if(i == j) continue;
				for(int k = 1;k <= n;k++){ //M
					if(k == i || k == j) continue;
					if(fabs(x[k]*2-x[i]-x[j])>eps || fabs(y[k]*2-y[i]-y[j])>eps) continue;
					if(fabs(dis(i,k) - dis(j,k)) > eps) continue; //判中点
//					cout << i << " " << j << " " << k << endl; 
					for(int l = 1;l <= n;l++){ //C
						if(l == i || l == j || l == k) continue;
						if(fabs(dis(i,j)-dis(l,k)) > eps) continue;
						if(fabs(dis(i,k)+dis(k,l)-dis(i,l)) > eps) continue;
						ans++;
					}
				}
			}
		}
		printf("Set #%d: %d\n\n",e,ans/2);
	}
    return 0;
}

B - Count the Dividing Pairs

题目描述

Number Theory provides many fascinating properties. You have most likely written programs dealing with different groups of numbers such as Prime, Perfect, Amicable, Happy, Powerful, and Untouchable numbers, just to name a few. In this problem, you’ll attack yet another fascinating property of numbers, one dealing with pairs of numbers.
An integer D is said to be a proper divisor of an integer N if D ≠ N and there exist an integer Q such that N = Q * D. For example, 4 is a proper divisor of 8 and 5 is a proper divisor of 15, but 9 is not a proper divisor of 9 and 6 is not a proper divisor of 8. Note that zero is not a proper divisor of any number but all numbers (except zero) are proper divisors of zero.
We will call (D, N) as defined above “proper dividing pairs”.
The Problem:
Given a list of integers A = {A1, A2, …, Ap}, you are to determine (count) the number of proper dividing pairs (Ai, Aj), where 1 ≤ i, j ≤ p.

Input

The first input line contains a positive integer, n, indicating the number of test cases to process. Each test case starts with an integer, p (2 ≤ p ≤ 1000,000), indicating the number of integers in the list. The following input line will provide p integers, Ai (0 ≤ Ai ≤ 10,000,000).

Output

For each test case, print “Test case #t: m”, where t indicates the case number starting with 1 and m indicates the number of proper dividing pairs. Leave a blank line after the output for each test case.
Note that, as illustrated in Sample Input/Output, duplicate values in the input list are considered as different elements in the list and they each contribute to the total count (proper dividing pairs).

Sample Input

5
3
1 2 3
4
1 2 3 1
2
7 5
3
29 0 17
10
32 16 8 4 2 2 4 8 16 32

Sample Output

Test case #1: 2

Test case #2: 4

Test case #3: 0

Test case #4: 2

Test case #5: 40

AC代码

#include<bits/stdc++.h>
#define pb push_back
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<double,double> PAIR;
const int N = 1e7+5;
const int INF = 0x3f3f3f3f;
int dp[N];
int main()
{
	int n,T,cas = 0;
    cin >> T;
    while(T--){
    	int x,Max = 0;
    	ll ans = 0;
    	memset(dp,0,sizeof(dp));
    	
    	cin >> n;
    	for(int i = 1;i <= n;++i) cin >> x,dp[x]++,Max = max(Max,x);
    	ans += (ll)dp[0]*(ll)(n-dp[0]);
    	ans += (ll)dp[1]*(ll)(n-dp[1]-dp[0]);
    	
    	for(int i = 2;i <= Max;++i){
    		if(dp[i]){
    			ll t = dp[i];
    			for(int j = (i << 1);j <= Max;j += i){
    				if(dp[j]) ans += t*dp[j];
				}
			}
		}
		printf("Test case #%d: %lld\n\n",++cas,ans);
	}
    return 0;
}

(三)UCF Local Programming Contest 2016

A - Automatic Control Machine

题目描述

Problem Description
The company has produced an Automatic Control Machine (ACM for short) that is very popular. Due to its complete and powerful features, the company is preparing to redesign after years of sales. The new version of the ACM is still subject to a number of tests to determine the reliability of the product before it goes on the market. Because there are so many features,each test dataset can only detect several of them. Of course, the product must be availableafter all features have been tested. Since each test has time and material costs, they like todo the test as less as possible. Assume that running each test dataset costs the same, yourjob is finding the minimum number of test datasets that can cover the test of all features. Forexample, if there are 55 features that need to be tested, and there are 66 test datasets each cancover the features as follows:
Test dataset aa: 11
Test dataset bb: 2, 52,5
Test dataset cc: 2, 3, 42,3,4
Test dataset dd: 1, 3, 51,3,5
Test dataset ee: 1, 3, 41,3,4
Test dataset ff: 3, 53,5
Although {a, b, c}{a,b,c} may do the job, but {c, d}{c,d} will do the job better in the way of saving time and money.

Input

The first line of the input file contains one positive integer T representing the number of machines. For each machine, the first line consists of two integers n and m representing the features of machine that has to be tested and the number of test datasets. It follows by m lines, each line has a binary string of length n, showing whether the features can be detected by the test dataset or not (1 means yes, 0 means no).

Output

Output T lines. Each of them should be the minimum number of test dataset needed to test all features for that machine. If it is not possible to test all functions for the machine, output -1.
Technical Specification
The number of machines 0 < T ≤ 10
The number of functions to be tested 0 < n ≤ 500
The number of test data 0 < m ≤ 15

Sample Input

5
3 3
100
011
111
5 6
10000
01001
01110
00111
10110
00101
6 7
000010
011000
100100
001000
000010
010000
110001
7 6
1001001
1001000
0001101
0010110
0110011
0100001
2 1
01

Sample Output

1
2
4
3
-1

AC代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;
const ll N = 2000;
const int INF = 0x3f3f3f3f;
const double eps = 1e-7;
string s[25];
int bit[25];

int main(){
    int n,m,T;
    cin >> T;
    while(T--){
    	int ans = INF;
    	cin >> n >> m;
    	
    	for(int i = 1;i <= m;++i) cin >> s[i];
    	for(int i = 1;i < (1 << m);++i){
    		int num = i,now = 1,cnt = 0;
    		while(num){
    			if(num & 1) bit[++cnt] = now;
    			num >>= 1;
    			now++;
			}
			if(cnt >= ans) continue;
			
			bool flag;
			for(int i = 0;i < n;++i){
				flag = 0;
				for(int j = 1;j <= cnt;++j){
					if(s[bit[j]][i] == '1'){
						flag = 1;
						break;
					}
				}
				if(!flag) break;
			}
			if(flag) ans = min(ans,cnt);
		}
		
		printf("%d\n",ans == INF ?-1 :ans);
	}
    return 0;
}

(四)UCF Local Programming Contest 2017

A - Simplified Keyboard

题目描述

Consider a simplified keyboard consisting of the 26 lowercase letters as illustrated below:
在这里插入图片描述
We define the neighbors of a key (letter) as all the letters adjacent to it. For example, the neighbors of ‘a’ are {b, k, j}, neighbors of ‘b’ are {a, c, l, k, j}, neighbors of ‘n’ are {d, e, f, o, x, w, v, m}, and neighbors of ‘z’ are {p, q, r, y}.
The Problem:
Given two words consisting of lowercase letters only, you are to determine which of the following three cases applies to them:

  1. identical: this is when the two words are of the same length and they match letter-byletter. For example, “cool” and “cool” are identical, “cool” and “col” are not, and “cool” and “colo” are not.
  2. similar: this is when the two words are of the same length, they are not identical words, and each corresponding two letters either match or are neighbors. For example, “aaaaa” and “abkja” are similar, “moon” and “done” are similar, “knq” and “bxz” are similar, but “ab” and “cb” are not (because of ‘a’ in the first word and the corresponding ‘c’ in the second word).
  3. different: this is when neither of the above two cases applies to the two words, i.e., they are not identical and they are not similar. For example, “ab” and “abc” are different, “ab” and “az” are different, and “az” and “za” are different.

Input

The first input line contains a positive integer, n, indicating the number of test cases to process. Each of the following n input lines represents a test case, consisting of two words separated by one space. Each word consists of lowercase letters only and will be between 1 and 20 letters, inclusive.

Output

For each test case, output one line. That line should contain the digit (number) 1, 2, or 3, to indicate which of the above three cases applies to the two input words.

Sample Input

7
a k
a a
a z
cool cool
aaaaa abkja
ab abc
az za

Sample Output

2
1
3
1
2
3
3

理解

不知道大家有没有什么其他简单方法做的
我干脆把键盘用数组模拟了,然后找当前字母位置
然后遍历周围

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const int mod = 998244353;
char mp[5][15]={
	{'1','1','1','1','1','1','1','1','1','1','1'},
	{'1','a','b','c','d','e','f','g','h','i','1'},
	{'1','j','k','l','m','n','o','p','q','r','1'},
	{'1','s','t','u','v','w','x','y','z','1','1'},
	{'1','1','1','1','1','1','1','1','1','1','1'},
};
int main(){
	int cas;
	cin >> cas;
	while(cas--){
		string s1,s2;
		cin >> s1 >> s2;
		if(s1 == s2) printf("1\n");
		else{
			int l1 = s1.size(),l2 = s2.size();
			if(l1 != l2) printf("3\n");
			else{
				int fl = 1;
				for(int i = 0;i < l1;i++){
					if(s1[i] != s2[i]){
						int x = 0,y = 0;
						for(int j = 1;j <= 3;j++){
							for(int k = 1;k <= 9;k++){
//								cout << mp[j][k]<<endl;
								if(mp[j][k] == s1[i]){
									x = j;
									y = k;
								}
							}
							if(x&&y) break;
						}
//						cout <<"x = "<<x <<" y = "<<y<<endl;
						int f = 0;
						for(int j = x-1;j <= x+1;j++){
							for(int k =y-1;k <=y+1;k++){
								if(mp[j][k] == s2[i]){
									f = 1;
									break;
								}
							}
							if(f) break;
						}
						if(!f){
							fl = 0;
							break;
						}
					}
				}
				if(fl) printf("2\n");
				else printf("3\n");
			}
		}
	}
	return 0;
}

B - Editor Navigation

题目描述

You are using a very simple text editor to create a document. You have typed in several lines, with the flashing cursor advancing as you type, but then you see a mistake on a previous line. Unfortunately, the mouse doesn’t work! You will have to press arrow keys to move the cursor back to the position where you can fix the mistake. Of course, you want to get to this position as quickly as possible.
在这里插入图片描述
This simple editor uses a monospace font, so each character is exactly the same width. The cursor can be at the beginning of the line (before the first character), end of the line (after the last character), or at a horizontal position between two characters on a given line. The following keys can be pressed to move the cursor (each keypress is independent of any preceding keypress):
在这里插入图片描述
在这里插入图片描述
The Problem:
Given the line lengths of a text file that was loaded in this simple editor, along with the current cursor position and a different, desired cursor position (e.g., to fix a mistake), you are to determine the minimum number of keypresses, using arrow keys only, required to move the cursor to the desired position.

Input

The first input line contains a positive integer, n, indicating the number of editor navigation scenarios to process. Each scenario will occupy exactly 4 input lines. The first line of each scenario contains an integer f (1 ≤ f ≤ 120), indicating the number of lines of text in the file that is loaded in the editor. The next input line contains f integers, s1 to sf, where each value si (0 ≤ si ≤ 80) indicates the number of characters on line i of the file; the values will be separated by exactly one space. A value si = 0 means that there are no characters on line i. The newline character (common character indicating end of a line) does not count as a character on the line. The third input line of each scenario will contain two integers (separated by a space) providing the current cursor position in the file: rc (1 ≤ rc ≤ f) and cc (0 ≤ cc ≤ 80), where rc represents the line of the file, counting from 1 (as with i), and cc represents the horizontal position of the cursor on that line, 0 for the beginning (before the first character). It is guaranteed that the cursor position is valid, so if, for instance, rc = 17 and s17 = 56, then 0 ≤ cc ≤ 56; the maximum value of cc is the end of the line. The fourth input line of each scenario is similar to the third and indicates the desired cursor position to begin fixing the mistake, i.e., this line consists of two integers separated by a space, rm (1 ≤ rm ≤ f) and cm (0 ≤ cm ≤ 80). The constraints on the values for rc and cc also apply to rm and cm.

Output

For each scenario in the input, output a single integer on a line by itself indicating the minimum number of keypresses needed to move the cursor from its current position (rc, cc) to the desired position (rm, cm) for fixing the mistake.

Sample Input

2
7
39 20 57 54 14 38 31
7 31
3 39
3
15 30 20
1 12
3 3

Sample Output

21
8

样例解释

For Case #1, one possible sequence for the minimum number of keypresses to move the cursor from its current position to the desired position is: Up, Up, Right, Up, Left, Up, Left 15 times.

理解

模拟题,如果返回上一行时,字符数小于当前位置,则直接到上一行末尾
如果一行有n个字符 则该行有0 - n个位置

AC代码

#include <bits/stdc++.h>
#define x first
#define y second
#define mk make_pair
using namespace std;
typedef long long ll;
typedef pair <int,int> PAIR;
const int N = 2e2+5;

int a[N],mp[N][N];
bool vis[N][N];


inline int bfs(int sx,int sy,int ex,int ey,int n){
	memset(vis,0,sizeof(vis));
	memset(mp,0,sizeof(mp));
	vis[sx][sy] = 1;
	
	queue <PAIR> q;
	q.push(mk(sx,sy));
	
	while(!q.empty()){
		PAIR now = q.front();q.pop();
		int nowx = now.x;
		int nowy = now.y;
		
		if(nowx == ex && nowy == ey)
			return mp[ex][ey];
			
		// 上下移动 
		if(nowx > 1){
			int tx,ty;
			if(a[nowx-1] >= nowy) tx = nowx-1,ty = nowy;
			else tx = nowx-1,ty = a[nowx-1];
			
			if(!vis[tx][ty]){
				vis[ty][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
		if(nowx < n){
			int tx,ty;
			if(a[nowx+1] >= nowy) tx = nowx+1,ty = nowy;
			else tx = nowx+1,ty = a[nowx+1];
			
			if(!vis[tx][ty]){
				vis[tx][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
		
		// 左右移动
		int tx,ty;
		if(nowy < a[nowx]){
			tx = nowx;
			ty = nowy+1;
			
			if(!vis[tx][ty]){
				vis[tx][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
		else if(nowx < n){
			tx = nowx+1;
			ty = 0;
				
			if(!vis[tx][ty]){
				vis[tx][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
		
		if(nowy > 0){
			tx = nowx;
			ty = nowy-1;
			
			if(!vis[tx][ty]){
				vis[tx][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
		else if(nowx > 1){
			tx = nowx-1;
			ty = a[nowx-1];
			
			if(!vis[tx][ty]){
				vis[tx][ty] = 1;
				mp[tx][ty] = mp[nowx][nowy]+1;
				q.push(mk(tx,ty));
			}
		}
	}
}

int main(){
    int n,cas;
    cin >> cas;
    int sx,sy,ex,ey;
    while(cas--){
    	cin >> n;
    	for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
    	scanf("%d %d",&sx,&sy);
    	scanf("%d %d",&ex,&ey);
    	int ans = bfs(sx,sy,ex,ey,n);
    	printf("%d\n",ans);
	}
    return 0;
}

C - Multimodal Transport

题目描述

New methods of shipping goods have transformed the transportation industry and helped usher in an era of global commerce. Nowadays, someone can click a few buttons and have an item leave a factory on the other side of the world and show up at their doorstep the next day. To help accomplish this, there are a number of modes of transport within the shipping industry. The four most common are: air, boat, rail and truck.
Transportation companies tend to keep the mode of transport consistent throughout a packages journey (route/path). However, when customers are not very time sensitive, often times the cheapest way to move a package from one location to another is to use more than one mode of transport. One has to be careful, though, as additional costs are incurred when switching between transport modes within a city on the package path. (Switching transport mode refers to a package leaving a city in a different mode than it arrived at the city, e.g., the package arrived by air and leaves by truck.)
A new startup, KnightShip, has asked for your help in figuring out the cheapest way to ship packages when switching between transportation modes is acceptable.
The Problem:
Given the costs for various modes of transport between cities, and the cost of switching mode within a city, calculate the lowest cost to transport an item from an origin to a destination.

Input

The first input line contains a positive integer, n, indicating the number of test cases to process. Each test case will contain multiple input lines. The first line of each test case will contain an integer, c (2 ≤ c ≤ 400), representing the number of cities within the transportation network. Each of the following c input lines contains two values: a string (1 to 20 uppercase letters, inclusive), representing the name of a city and an integer (between 1 and 1000, inclusive), representing the cost of changing the transport mode within that city.
The city information for a test case is followed by the route information for the test case. There will be an input line containing one integer, r (1 ≤ r ≤ 40000), representing the number of route segments in the network. This will be followed by a listing of all route segments, one per line. Each route segment will contain four values: p, q, representing two cities from the previous list, m, representing the transport mode (one of four values AIR, SEA, RAIL, TRUCK) for that route segment, and an integer v (1 ≤ v ≤ 1000), representing the cost to ship a package between the two cities (either direction). Note that there may be no route segments for a particular transport mode. There will be no duplicate city pair within a given mode of transport, but different transport modes (even all four modes) can exist between the same two cities.
The last input line for a test case contains two distinct cities o and d which represent the origin and destination cities for which we want the minimum cost to ship a package. Cities o and d are guaranteed to have a path (of finite cost) that exists between them. Any mode of transport can be used to leave city o and any mode can be used to reach city d (they don’t necessarily need to match). The transport mode can change in the intermediate stages as well.

Output

For each test case, output a single integer on a line by itself indicating the minimum cost to move a package from city o to city d.

Sample Input

2
4
ORLANDO 10
TAMPA 15
MIAMI 5
JACKSONVILLE 10
7
TAMPA JACKSONVILLE AIR 100
MIAMI TAMPA SEA 70
JACKSONVILLE MIAMI RAIL 45
ORLANDO JACKSONVILLE TRUCK 85
TAMPA ORLANDO RAIL 10
MIAMI JACKSONVILLE SEA 15
ORLANDO MIAMI TRUCK 15
JACKSONVILLE TAMPA
2
ORLANDO 15
TAMPA 10
3
ORLANDO TAMPA AIR 7
TAMPA ORLANDO TRUCK 3
ORLANDO TAMPA RAIL 19
ORLANDO TAMPA

Sample Output

55
3

AC代码

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 4e2+7;
const int INF = 0x3f3f3f3f;

vector <int> e[maxn];
map <string,int> mp;
int change[maxn],c[maxn][maxn][4],dp[maxn][4];
bool vis[maxn][4];
struct node{
	int x,d,fs;
	node(int x,int d,int fs):x(x),d(d),fs(fs){}
	friend bool operator < (node A,node B){
		return A.d > B.d;
	}
};
int get(string temp){
	if(temp == "AIR") return 0;
	if(temp == "SEA") return 1;
	if(temp == "RAIL") return 2;
	if(temp == "TRUCK") return 3;
}
void dijkstra(int s){
	for(int i = 0;i < 4;++i) dp[s][i] = 0;
	priority_queue <node> q;
	q.push(node(s,0,0));
	q.push(node(s,0,1));
	q.push(node(s,0,2));
	q.push(node(s,0,3));	
	while(!q.empty()){
		node now = q.top();q.pop();
		if(vis[now.x][now.fs]) continue;
		vis[now.x][now.fs] = 1;		
		for(int i = 0;i < e[now.x].size();++i){
			int v = e[now.x][i];			
			for(int j = 0;j < 4;++j){
				if(c[now.x][v][j]){
					int is_change = 0;
					if(now.fs != j) is_change += change[now.x];
					if(dp[v][j] > now.d+c[now.x][v][j]+is_change){
						dp[v][j] = now.d+c[now.x][v][j]+is_change;
						q.push(node(v,dp[v][j],j));
					}
				}
			}
		}
	}	
	return ;
}

int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--){
    	int f,w,n,m;
    	string s,t,fs;
    	mp.clear();
    	memset(c,0,sizeof(c));
    	memset(dp,INF,sizeof(dp));
    	memset(vis,0,sizeof(vis));
		scanf("%d",&n);
    	for(int i = 1;i <= n;++i){
    		e[i].clear();
    		cin >> s >> w;
    		mp[s] = i;
    		change[i] = w;
		}
		
		scanf("%d",&m);
		while(m--){
			cin >> s >> t >> fs >> w;
			int u = mp[s];
			int v = mp[t];
			int f = get(fs);
			e[u].pb(v);
			e[v].pb(u);
			c[u][v][f] = w;
			c[v][u][f] = w;
		}		
		cin >> s >> t;
		int u = mp[s];
		int v = mp[t];
		dijkstra(u);
		int ans = INF;
		for(int i = 0;i < 4;++i) ans = min(ans,dp[v][i]);
		printf("%d\n",ans);
	}
    return 0;
}

(五)ICPC Latin American Regional Contests 2019

A - Eggfruit Cake

题目描述

Today is Jaime’s birthday and, to celebrate, his friends ordered a cake decorated with eggfruits and persimmons. When the cake arrived, to their surprise, they noticed that the bakery didn’t use equal amounts of eggfruits and persimmons, but just randomly distributed the fruits over the cake’s border instead.
Jaime eats persimmons every day, so he was eager to try some eggfruit on his birthday.However, as he doesn’t want to eat too much, his cake slice should be decorated with at most S fruits. Since Jaime doesn’t like when a fruit is cut into parts, each fruit should either be entirely in his slice or be left in the rest of the cake. The problem is, with the fruits distributed in such a chaotic order, his friends are having trouble cutting a suitable slice for him.
Jaime is about to complain that his friends are taking too long to cut his slice, but in order to do so, he needs to know how many different slices with at least one eggfruit and containing at most S fruits there are. A slice is defined just based on the set of fruits it contains. As Jaime is quite focused on details, he is able to distinguish any two fruits, even if both fruits are of the same type. Hence, two slices are considered different when they do not contain exactly the same set of fruits. The following picture shows a possible cake, as well as the six different slices with at most S = 2 fruits that can be cut from it.
在这里插入图片描述

Input

The first line contains a circular string B (3 ≤ |B| ≤ 1e5) describing the border of the cake.Each character of B is either the uppercase letter “E” or the uppercase letter “P”, indicatingrespectively that there’s an eggfruit or a persimmon at the border of the cake. The second linecontains an integer S (1 ≤ S < |B|) representing the maximum number of fruits that a slicecan contain.

Output

Output a single line with an integer indicating the number of different slices with at mostS fruits and at least one eggfruit.

Sample Input

样例输入1
PEPEP
2
样例输入2
EPE
1
样例输入3
EPEP
2

Sample Output

样例输出1
6
样例输出2
2
样例输出3
6

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
int a[maxn];

int main(){
	string s;
	cin >> s;
	int l = s.size();
	int x;
	scanf("%d",&x);
	int mx = -1;
	 for(int i = 0;i < l;i++)
    	if(s[i] == 'E') mx = max(mx,i);
    ll sum = 0;
	s += s;
	for(int i = l;i < s.size();i++){
		if(s[i] == 'E') mx = max(mx,i);
		if(mx == -1) continue;
		sum += max(0,mx-max(0,i-x+1)+1);
	}
	cout << sum << endl;
    return 0;
}

(六)ICPC Southeastern Europe Contest 2019

A - Absolute Game

题目描述

Alice and Bob are playing a game. Alice has an array a of n integers, Bob has an array b of n integers. In each turn, a player removes one element of his array. Players take turns alternately. Alice goes first.
The game ends when both arrays contain exactly one element. Let x be the last element in Alice’s array and y be the last element in Bob’s array. Alice wants to maximize the absolute difference between x and y while Bob wants to minimize this value. Both players are playing optimally.
Find what will be the final value of the game.

Input

The first line contains a single integer n (1≤n≤1000) — the number of values in each array.
The second line contains n space-separated integers a1,a2,…,an (1 ≤ ai ≤ 10^9) — the numbers in Alice’s array.
The third line contains n space-separated integers b1,b2,…,bn (1 ≤ bi ≤ 10^9)— the numbers in Bob’s array.

Output

Print the absolute difference between x and y if both players are playing optimally.

Sample Input

样例输入1
4
2 14 7 14
5 10 9 22
样例输入2
1
14
42

Sample Output

样例输出1
4
样例输出2
28

理解

因为两人都是最优解所以
只要暴力循环找每个ai对应差值最小的bi的差里的最大即可

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
int a[maxn],b[maxn];

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		scanf("%d",&a[i]);
	}
	for(int i = 1;i <= n;i++) scanf("%d",&b[i]);
	int ans = 0;
	for(int i = 1;i <= n;i++){
		int cnt = inf;
		for(int j = 1;j <= n;j++)
			cnt = min(cnt,abs(a[i]-b[j]));
		ans = max(ans,cnt);
	}
	printf("%d\n",ans);
    return 0;
}

B - Graph and Cycles

题目描述

There is an undirected weighted complete graph of n vertices where n is odd.
Let’s define a cycle-array of size k as an array of edges [e1,e2,…,ek] that has the following properties:
k is greater than 1.
For any i from 1 to k, an edge ei has exactly one common vertex with edge ei−1 and exactly one common vertex with edge ei+1 and these vertices are distinct (consider e0 =ek , ek+1 =e1 ).
It is obvious that edges in a cycle-array form a cycle.
Let’s define f(e1,e2) as a function that takes edges e1 and e2 as parameters and returns the maximum between the weights of e1 and e2 .
Let’s say that we have a cycle-array C=[e1,e2,…,ek] . Let’s define the price of a cycle-array as the sum of f(ei,ei+1) for all i from 1 to k (consider ek+1=e1 ).
Let’s define a cycle-split of a graph as a set of non-intersecting cycle-arrays, such that the union of them contains all of the edges of the graph. Let’s define the price of a cycle-split as the sum of prices of the arrays that belong to it.
There might be many possible cycle-splits of a graph. Given a graph, your task is to find the cycle-split with the minimum price and print the price of it

Input

The first line contains one integer n (3 ≤ n ≤ 999 , n is odd) — the number of nodes in the graph.
Each of the following n⋅(n−1) ÷2 lines contain three space-separated integers u, v and w (1 ≤ u,v ≤ n,u≠v,1 ≤ w ≤ 10^9 ), meaning that there is an edge between the nodes u and v that has weight w.

Output

Print one integer — the minimum possible price of a cycle-split of the graph.

Sample Input

样例输入1
3
1 2 1
2 3 1
3 1 1
样例输入2
5
4 5 4
1 3 4
1 2 4
3 2 3
3 5 2
1 4 3
4 2 2
1 5 4
5 2 4
3 4 2

Sample Output

样例输出1
3
样例输出2
35

理解

判每个点上所有边
排序后两两取最大即可

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 7;
const double pi = acos(-1);
const int mod = 998244353;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
vector<int> e[1007];

int main(){
	int n;
	scanf("%d",&n);
	int k = n * (n-1) / 2;
	while(k--){
		int u,v,w;
		scanf("%d %d %d",&u,&v,&w);
		e[u].push_back(w);
		e[v].push_back(w);
	}
	ll ans = 0;
	for(int i = 1;i <= n;i++){
		sort(e[i].begin(),e[i].end());
		for(int j = 1;j < n-1;j+=2){
			ans += e[i][j];
		}
	}
	cout << ans << endl;
    return 0;
}

(三)我的感想

我是莫得感情的划水机器

鸽了两周,终于补上了,太感人le,我以为我会我一直拖延下去的,还是疯狂掉分的惹某,感觉现在题目都鬼精鬼精的,一眼看不透本质,老是想的太复杂,觉得会t不敢写,其实理解过来很多都可以处理掉。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值