开学第一周(习题+感悟)

(一)UCF Local Programming Contest 2015

A - Rain Gauge

题目描述

When going to your internship you got a nice apartment with a skylight. However, one crazy party later and you now have a square-shaped hole where your skylight used to be. Rather than telling the landlord, you decided you would “fix” it by putting a circular pot to collect the water but, as the saying goes, round peg square hole. You need to determine how much of the square the circle covers to help you determine if you should buy a larger pot. Don’t worry about the area not covered; you can do multiplication and subtraction easily in your head.
在这里插入图片描述
Given the radius of a circular pot and the length of the square skylight, calculate the amount of skylight rain area covered by the pot assuming the two shapes have the same center (i.e., are coaxial) with respect to the direction rain falls from (up). In other words, the center of the square will be directly above the center of the circle. See the picture for an example; let up be the direction from above the page, while the dotted square is the skylight and the solid circle is the pot to collect water.

Input

The first input line contains a positive integer, n, indicating the number of scenarios to check. Each of the following n lines contains a pair of integers, s, r (1 ≤ s ≤ 100,1 ≤ r ≤ 100), which represents the length of the side of the skylight and the radius of the pot, respectively.

Output

For each scenario, output a single decimal representing the area under the skylight that is covered by the pot. Round the answers to two decimal places (e.g., 1.234 rounds to 1.23 and 1.235 rounds to 1.24). For this problem, use 3.14159265358979 as the value of pi

Sample Input

3
1 1
8 5
10 4

Sample Output

1.00
62.19
50.27

理解

给定一个正方形和一个圆,已知中心一致,求重合面积
分类讨论
当 2R ≥ √2L 时 面积为 L^2
当 2R ≤ L 时,面积为πR^2
其余情况如下图

在这里插入图片描述

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 7;
const int mod = 1e9 + 7;
const double pi = 3.14159265358979;

int main(){
	int cas;
	scanf("%d",&cas);
	while(cas--){
		double l,r;
		scanf("%lf %lf",&l,&r);
		if(l >= 2*r) printf("%.2lf\n",pi*r*r);
		else if(2*r >= sqrt(2*l*l)) printf("%.2lf\n",l*l);
		else{
			double a,s,t;
        	a = acos(l/2/r);
        	s = 2*a*r*r/2;
        	t = r*r*sin(2*a)/2;
        	printf("%.2lf\n",pi*r*r-4*(s-t));
		}
	}
	return 0;
}

B - Balanced Strings

题目描述

Being an individual obsessed with balancing and trying to find strings that meet that criteria, you have begun a new endeavor to study the curious structure of what we will call balanced strings.

Balanced strings are strings that maintain an equal ratio of consonants to vowels in all of their substrings. What? You don’t know the difference between a consonant and a vowel? Vowels are the characters ‘a’, ‘e’, ‘i’, ‘o’, ‘u’ and sometimes ‘y’. Actually, you don’t like the character ‘y’ because this makes the problem much harder. What was the difficulty level of this problem again? Oh yeah Medium! We can’t have a problem about consonants and vowels that makes ‘y’ sometimes a vowel! That would make the problem a Hard and too many hard problems is a very bad thing. Being obsessed with balance, you have decided that ‘y’ will be included with the vowels. That way, there are 6 vowels and 20 consonants. A nice balanced even number of both! Oh! I almost forgot! A consonant is any letter that is not a vowel. Also to simplify things (this is a medium problem after all!), we will consider strings composed of lowercase letters only.

Now you are ready to understand balanced strings! A balanced string is a string that has an equal number of consonants and vowels in all of its substrings. Well… not all of its substrings. Just the substrings of even length! For example, the string “orooji” has the following set of even- length substrings: {“or”, “ro”, “oo”, “oj”, “ji”, “oroo”, “rooj”, “ooji”, “orooji”}. In that set the following substrings are unbalanced: {“oo”, “oroo”, “ooji”, “orooji”}. That is, the substrings do not contain an equal number of vowels and consonants. So, the string “orooji” is not balanced. But a string like “arup” is balanced. The requisite even-length substrings are: {“ar”, “ru”, “up”, “arup”} and all these substrings are balanced (have the same number of vowels and consonants), thus the string “arup” is balanced. Note that a balanced string may contain an odd number of characters, e.g., the string “ali” is balanced since all its even-length substrings ({“al”, “li”}) are balanced.
Now you want to take words and erase some of the letters and replace them with new letters to form balanced strings. Since this is a medium problem, we’ve taken the liberty of erasing some of the letters for you and replaced them with ‘?’ characters. See! The problem is already halfway solved!
The Problem:
Given a string of lowercase letters and ‘?’ characters, count the number of ways to replace all the ‘?’ with lowercase letters such that the string results in a balanced string. Two ways are considered different if there exists some i such that the i^th character in one string differs from the i^th character of the other string. Note that all the ‘?’ do not have to be replaced by the same letter.

Input

The first input line contains a positive integer, n, indicating the number of strings to balance. The strings are on the following n input lines, one string per line. Each string contains only lowercase letters and/or ‘?’ characters. Assume each input string has at least one character and at most 100 characters.

Output

For each string, output “String #d: v” where v is the number of ways to replace the questions marks with lower case letters. It is guaranteed that v will fit in a signed 64-bit integer for the strings we provide. Leave a blank line after the output for each string.

Sample Input

7
orooji
al?
a?i
g?ha
a?u?
???
arup

Sample Output

String #1: 0

String #2: 6

String #3: 20

String #4: 6

String #5: 400

String #6: 1117952409600000000

String #7: 1

理解

起先写的时候是跟大佬学的dp推导
然后看题解的时候发现了一位奆佬推得的数学式子
思路如下
一个字符串的所有偶数长度元音字母与辅音字母的个数相同
该字符串一定是 “元辅元辅元辅” 这样元音和辅音交错的形式
若原字符串全为’?’,则答案为6^⌊N/2⌋ × 20^(N-[N/2]) + 201 × 6(N-[N/2])。否则设应当是元音的’?’数量为x,应当是辅音的’?’数量为y,答案为6x × 20^y。

奆佬代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define LL long long
string S;
int T,Num=0;

LL EXP(LL b,LL n){
    if(n==0LL) return 1LL;
    LL x=1,Power=b;
    while(n){
        if(n&1) x*=Power;
        Power*=Power;
        n>>=1;
    }
    return x;
}

int main(){
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--){
        cin>>S;++Num;
        cout<<"String #"<<Num<<": ";
        int Case=-1,Len=S.size();;
        for(int i=0;i<Len;++i){
            if(S[i]=='?') continue;
            else if(S[i]=='a' || S[i]=='e' || S[i]=='i' 
                || S[i]=='o' || S[i]=='u' || S[i]=='y'){
                Case=i%2;
                break;
            }
            else{Case=1-i%2;break;}
        }
        if(Case==-1){
            cout<<EXP(6,Len/2)*EXP(20,Len-Len/2)+
                EXP(20,Len/2)*EXP(6,Len-Len/2)<<endl<<endl;
            continue;
        }
        bool flag=false;
        int Count0=0,Count1=0;
        for(register int i=0;i<Len;++i){
            if(S[i]=='?'){
                if(i%2==0) ++Count0;
                else ++Count1;
            }
            else if(S[i]=='a' || S[i]=='e' || S[i]=='i' 
                || S[i]=='o' || S[i]=='u' || S[i]=='y'){
                if(i%2!=Case) {flag=true;break;}
            }
            else if(i%2!=1-Case){flag=true;break;}
        }
        if(flag){cout<<0<<endl<<endl;continue;}
        if(Case==0) cout<<EXP(6,Count0)*EXP(20,Count1)<<endl;
        else cout<<EXP(20,Count0)*EXP(6,Count1)<<endl;
        cout<<endl;
    }
    return 0;
}

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
const int mod = 1e9 + 7;
ll dp[107][3];
map<char,int> mp;

int main(){
	int cas;
	scanf("%d",&cas);
	string str = "aeiouy";
	for(int i = 0;i < 6;i++) mp[str[i]] = 1;
	int cnt = 1;
	int e = 1;
	while(cas--){
		memset(dp,0,sizeof(dp));
		string s;
		cin >> s;
		printf("String #%d: ",e++);
		if(s[0]=='?') dp[0][1] = 6,dp[0][2] = 20;
		else if(mp[s[0]]) dp[0][1] = 1;
		else dp[0][2] = 1;
		int l = s.size();
		for(int i = 1;i < l;i++){
			if(s[i] != '?'){
				if(mp[s[i]]) dp[i][1] = dp[i-1][2];
				else dp[i][2] = dp[i-1][1];
			}
			else dp[i][2] = dp[i-1][1]*20,dp[i][1] = dp[i-1][2]*6;
		}
		printf("%lld\n\n",dp[l-1][1]+dp[l-1][2]);
	}
	return 0;
}

(二)ICPC North Central NA Contest 2017

A - Pokemon Go Go

题目描述

Always Catch your Mon, Inc., (also know as ACM), wants to create a new product, called Pokémon Go Go. Users can purchase this application to help them play Pokémon go. The software accesses the poké stop locations near the current location as well as a list of Pokémon that can be found at each stop. The application then computes the shortest route one can follow to catch all the unique Pokémon, and return to the starting point.
The program assumes that the user is in a city where travel is restricted to moving only in the north–south and east–west directions. The program also assumes that all poké stops are on the intersection of two roads.
For example, consider a case where the application finds five nearby poké stops. Each stop’s location is indicated by two integers, (r,c)(r,c), where rr is the number of blocks north of your starting position and cc is the number of blocks west of your starting position. Consider if the locations of the five poké stops are (5,9), (20,20), (1,1), (1,8)and (2,8) while the names of the Pokémon found at these stops are Evevee, Flareon, Flareon, Jolteon, and Umbreon, respectively. It is clear that one does not have to visit both the second and third stops, since the same Pokémon can be caught at either of them. The best route is to visit the first, fifth, fourth, and third stops (in that order) for a total distance of 2828 blocks, since:
The distance from (0,0) to (5,9) is 14.
The distance from (5,9) to (2,8) is 4.
The distance from (2,8) to (1,8) is 1.
The distance from (1,8) to (1,1) is 7.
The distance from (1,1) to (0,0) is 2.

Input

The input holds a single test case. The test case begins with a single integer nn, 0<n≤20, which indicates the number of poké stops to consider. Each of the next nn lines specifies the location of a poké stop and the name of a Pokémon that can be found there. The location is specified by two integers rr and cc separated by a single space, −100≤r,c≤100. The integers rr and cc indicate that the stop is rr blocks north and cc blocks east of the starting point. The location is followed by a single space and followed by the string pp indicating the name of the Pokémon that can be caught there. Names have between 1 and 25 letters (using only a–z and A–Z). The number of unique Pokémon is always less than or equal to 15. Multiple pokémon can reside at a single poké stop and are listed on separate lines.

Output

Give the shortest distance, in blocks, required to catch all the unique Pokémon.

Sample Input

5
5 9 Eevee
20 20 Flareon
1 1 Flareon
1 8 Jolteon
2 8 Umbreon

Sample Output

28

理解

首先预处理有几个不同的精灵种类
然后算出每个点到另一个点的距离消耗
然后i循环已经走过的点
j循环现在的点 k是下一个点

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e4 + 7;
const int mod = 1e9 + 7;
map<string,int> mp;
struct node{
	int x,y;
	string name;
}a[27];
int dis(node c,node b){
	return abs(c.x-b.x)+abs(c.y-b.y);
}
int dp[1<<22][22];
int main(){
	int n,kind = 0;
	scanf("%d",&n);
	a[0].x = 0;
    a[0].y = 0;
	for(int i = 1;i <= n;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		string s;
		cin >> s;
		a[i].x = x,a[i].y = y,a[i].name = s;
		if(!mp[s]) mp[s] = ++ kind;
	}
	for(int i = 0;i < (1<<n);i++){
		for(int j = 0;j < n;j++){
			dp[i][j] = inf;
		}
	}
	dp[0][0] = 0;
	for(int i = 0;i < n;i++){
		dp[(1<<i)][i] = abs(a[i+1].x)+abs(a[i+1].y);
	}
	for(int i = 1;i < (1<<n);i++){
		for(int j = 0;j < n;j++){
			if(i & (1<<j)){
				for(int k = 0;k < n;k++){
					if(!(i & (1 << k)))
					dp[i^(1<<k)][k] = min(dp[i^(1<<k)][k],dp[i][j]+dis(a[j+1],a[k+1]));
				}
			}
		}
	}
	int ans = inf;
	set<int> ss;
	for(int i = 0;i < (1<<n);i++){
		ss.clear();
		for(int j = 0;j < n;j++)
			if(i & (1 << j))
				ss.insert(mp[a[j+1].name]);
		if(ss.size() == kind){
			for(int j = 0;j < n;j++){
				ans = min(ans,dp[i][j]+dis(a[0],a[j+1]));
			}
		}
	}
	cout << ans << endl;
	return 0;
}

B - Is-A? Has-A? Who Knowz-A?

题目描述

Two familiar concepts in object oriented programming are the is-a and has-a relationships. Given two classes A and B, we say that A is-a B if A is a subclass of B; we say A has-a B if one of the fields of A is of type B. For example, we could imagine an object-oriented language (call it ICPC++) with code like that in Figure E.1, where the class Day is-a Time, the class Appointment is both a DateBook and a Reminder, and class Appointment has-a Day.
在这里插入图片描述
These two relationships are transitive. For example if A is-a B and B is-a C then it follows that A is-a C. This holds as well if we change all the is-a’s in the last sentence to has-a’s. It also works with combinations of is-a’s and has-a’s: in the example above, Appointment has-a Time, since it has-a Day and Day is-a Time. Similarly, if class DateBook has-a Year then Appointment has-a Year, since Appointment is-a DateBook.
In this problem you will be given a set of is-a and has-a relationships and a set of queries of the form A is/has-a B. You must determine if each query is true or false.

Input

Input starts with two integers n and m, (1≤n,m≤10000), where nn specifies the number of given is-a and has-a relationships and mm specifies the number of queries. The next nn lines each contain one given relationship in the form c1 r c2 where c1 and c2 are single-word class names, and rr is either the string “is-a” or “has-a”. Following this are mm queries, one per line, using the same format. There will be at most 500500 distinct class names in the n+m lines, and all class names in the last m lines will appear at least once in the initial n lines. All is-a and has-a relationships between the given classes can be deduced from the nn given relationships. Is-a relationships can not be circular (apart from the trivial identity “x is-a x”).

Output

For each query, display the query number (starting at one) and whether the query is true or false.

Sample Input

5 5
Day is-a Time
Appointment is-a Datebook
Appointment is-a Reminder
Appointment has-a Day
Datebook has-a Year
Day is-a Time
Time is-a Day
Appointment has-a Time
Appointment has-a Year
Day is-a Day

Sample Output

Query 1: true
Query 2: false
Query 3: true
Query 4: true
Query 5: true

理解

由题意可知
A is B	B is C	-> A is C
A has B	B is C	-> A has C
A is B	B has C	-> A has C
A has B	B has C	-> A has C
注意 A is A 是成立的
看看n的范围
所以我们可以利用 floyd 闭包传递来做(确信)

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 5e2 + 7;
const int mod = 1e9 + 7;
int cnt = 0;
map<string,int>mp;
int is[maxn][maxn],has[maxn][maxn];
void floyd(){
	for(int i = 1;i <= cnt;i++) is[i][i] = 1;
	for(int k = 1;k <= cnt;k++){
		for(int i = 1;i <= cnt;i++){
			for(int j = 1;j <= cnt;j++){
				if(is[i][k]&&is[k][j]) is[i][j] = 1;
				if(is[i][k]&&has[k][j]) has[i][j] = 1;
				if(has[i][k]&&is[k][j]) has[i][j] = 1;
				if(has[i][k]&&has[k][j]) has[i][j] = 1;
			}
		}
	} 
	return;
} 
int main(){
	int n,m;
	scanf("%d %d",&n,&m);
	string s1,s2,t;
	while(n--){
		cin >> s1;
		if(!mp[s1]) mp[s1] = ++cnt;
		cin >> t;
		cin >> s2;
		if(!mp[s2]) mp[s2] = ++cnt;
		if(t == "is-a") is[mp[s1]][mp[s2]] = 1;
		else has[mp[s1]][mp[s2]] = 1;
	}
	floyd();
	int cas = 1;
	while(m--){
		cin >> s1;
		if(!mp[s1]) mp[s1] = ++cnt;
		cin >> t;
		cin >> s2;
		if(!mp[s2]) mp[s2] = ++cnt;
		int f = 0;
		if(t == "is-a") f = is[mp[s1]][mp[s2]];
		else f = has[mp[s1]][mp[s2]];
		printf("Query %d: %s\n",cas++,f?"true":"false");
	}
	return 0;
}

C - Lost Map

题目描述

Somewhere in a mountainous region of the world is a collection of nn villages. Connecting these villages to one another is a series of roads, always running directly between two villages and allowing travel in both directions. Due to the treacherous landscape, building these roads is expensive, so the minimum number of roads have been constructed such that each village can reach every other village via a sequence of roads.
Trade between these villages is very important, since not every village has access to the same supply of natural resources. Many villages produce the same resource, however, so it is useful for villages to know their relative distance to other villages so that they can choose trading partners to minimize overall trading costs. Note that the distance between two villages aa and bb is the sum of the lengths of the individual roads on the shortest path that connects aa and bb.
A project has been underway to compute the distance between every pair of villages. This information has been incorporated in a table, along with a map that shows the layout of villages and roads that run between them. You have been assigned the task of distributing the table and map to all the villages for the betterment of the regional economy.
Unfortunately, not long after you were given this task, a gust of wind blew the map right out of your hand and into the countryside. Despite your best efforts of searching for it, you have been unable to locate it. You know that you could visit all the villages to reconstruct the map and THEN start distributing the map and table, but this will take twice as long as the original task and the villages will be very displeased with you. You wonder, maybe it’s possible to reconstruct the map given only the table?

Input

The first line of input will contain the integer n (2≤n≤2500), the number of villages in this region. The next nn lines will contain nn integers each. The j^th integer of the i^th line is the distance from village i to village j. All distances are greater than zero unless i=j, less than 10^7, and it is guaranteed that the distance from village i to village j is the same as the distance from village j to village i.

Output

For each test case, output n−1 lines with two integers u and v on each line, indicating that there is a road connecting villages uu and v in this region. Assume the villages are numbered from 1 to n. Any solution that outputs the original set of roads will be accepted.

Sample Input

样例输入1
4
0 1 1 2
1 0 2 3
1 2 0 3
2 3 3 0
样例输入2
7
0 2 9 1 4 3 3
2 0 11 1 6 3 3
9 11 0 10 5 12 12
1 1 10 0 5 2 2
4 6 5 5 0 7 7
3 3 12 2 7 0 4
3 3 12 2 7 4 0

Sample Output

样例输出1
1 2
1 3
1 4
样例输出2
1 4
1 5
2 4
3 5
4 6
4 7

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e3 + 507;
const int mod = 1e9 + 7;
struct node{
	int u,v,w;
	node(){}
	node(int u,int v,int w):u(u),v(v),w(w){}
}edge[maxn*maxn];
int pre[maxn];
bool cmp(node a,node b){
	return a.w < b.w;
}
int find(int x){
	return x == pre[x]?x:find(pre[x]);
}
void kal(int n,int m){
	int sum = 0;
	for(int i = 1;i <= m;i++){
		int u = edge[i].u;
		int v = edge[i].v;
		int w = edge[i].w;
		if(find(u) == find(v)) continue;
		pre[find(u)] = find(v);
		printf("%d %d\n",u,v);
		sum++;
		if(sum == n - 1) break;
	}
	return;
}
int main(){
	int n;
	int m = 0;
	scanf("%d",&n);
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			int w;
			scanf("%d",&w);
			if(i < j) edge[++m] = node(i,j,w);
		}
		pre[i] = i;
	}
	sort(edge+1,edge+1+m,cmp);
	kal(n,m);
	return 0;
	return 0;
}

(三)我的感想

我是莫得感情的划水机器

自从开学变上网课开始各大网站真的是很嚣张(确信),到处都是比赛(15555)作为蒟蒻当然是被虐。
dp与我纠缠多年依旧是别人点拨就懂自己写就不太行的挤牙膏状态。对于并查集什么的(除了一些细节错误)还是有运用的,(然鹅细节错误一直导致我以为自己拉错板子,其实是被我改错)依旧感恩某紫姓大佬一直以来对我这个睿智(傻)儿童不厌其烦的教导。


  1. N/2 ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值